关于 Record & TList 的一点吐槽

需求是把record 保存在TList中,并可以随时改变TList中Items的各项值。

 

 代码很简单:

   MyRec = record



        MyStr: string;



        constructor Create(AMyStr: string);



end;



 



TForm4 = class(TForm)



  Button1: TButton;



  procedure Button1Click(Sender: TObject);



        public



  MyList: TList<MyRec>;



end;



 



constructor MyRec.Create(AMyStr: string);



begin



    MyStr := AMyStr;



end;



 



 



procedure TForm4.Button1Click(Sender: TObject);



begin



    MyList := TList<MyRec>.Create;



    MyList.Add(MyRec.Create('str'));



    MyList.Items[0].MyStr := 'www'; //[Error] Unit4.pas(46): E2064 Left side cannot be assigned to



    ShowMessage(MyList.Items[0].MyStr);



end;

 

 

无法赋值?想了一下,大概是因为左侧取出的是变量值本身,而不是变量,所以无法赋值。那么我取值地址再赋值总可以吧?于是改动如下:

 

procedure TForm4.Button1Click(Sender: TObject);



var



    ps: ^string;



begin



    MyList := TList<MyRec>.Create;



    MyList.Add(MyRec.Create('str'));



    ps := @MyList.Items[0].MyStr; //[DCC Error] Unit4.pas(45): E2036 Variable required



    ps^ := 'www';



    ShowMessage(MyList.Items[0].MyStr);



end;

 

 

必须为变量?又想了一下,大概是因为左侧取出的是变量值本身,而不是变量,所以无法取地址。那没办法,只能改一下TList,了,于是改动如下

Tpye



PMyRec = ^MyRec;



 



procedure TForm4.Button1Click(Sender: TObject);



begin



    MyList := TList<PMyRec>.Create;



    MyList.Add(MyRec.Create('str')); //[DCC Error] Unit4.pas(42): E2010 Incompatible types: 'PMyRec' and 'MyRec'



    MyList.Items[0].MyStr := 'www';



    ShowMessage(MyList.Items[0].MyStr);



end;

 

 

要是Create能返回指针就好了。不多说,继续改:

procedure TForm4.Button1Click(Sender: TObject);



begin



    MyList := TList<PMyRec>.Create;



    MyList.Add(@MyRec.Create('str')); //[DCC Error] Unit4.pas(42): E2036 Variable required



    MyList.Items[0].MyStr := 'www';



    ShowMessage(MyList.Items[0].MyStr);



end;

 

 

……。继续改:

procedure TForm4.Button1Click(Sender: TObject);



var



    r: MyRec;



begin



    MyList := TList<PMyRec>.Create;



    r := MyRec.Create('str');



    MyList.Add(@r);



    MyList.Items[0].MyStr := 'www';



    ShowMessage(MyList.Items[0].MyStr);



end;

 

 

看起来似乎是可以了,但是:

procedure TForm4.Button2Click(Sender: TObject);



begin



    ShowMessage(MyList.Items[0].MyStr); // Access Violation!



end;

 

 

想了一下,大概是r的内存被释放了。于是改动如下:

procedure TForm4.Button1Click(Sender: TObject);



var



    p: PMyRec;



begin



    MyList := TList<PMyRec>.Create;



    New(p);



    p.Create('str');



    MyList.Add(p);



    MyList.Items[0].MyStr := 'www';



    ShowMessage(MyList.Items[0].MyStr);



end;

 

 

OK了,不过真是麻烦,不用的时候还要dispose。感觉没有C++灵活。

你可能感兴趣的:(list)