arrays – 包含动态数组的记录的通用列表
我有一个通用的记录列表.这些记录包含如下的动态数组
Type TMyRec=record MyArr:Array of Integer; Name: string; Completed: Boolean; end; var MyList:TList<TMyRec>; MyRec:TMyRec; 然后我创建列表并设置数组长度,如下所示 MyList:=TList<TMyRec>.Create; SetLength(MyRec.MyArr,5); MyRec.MyArr[0]:=8; // just for demonstration MyRec.Name:='Record 1'; MyRec.Completed:=true; MyList.Add(MyRec); 然后我更改MyArr中的数据,我也更改MyRec.Name并将另一项添加到列表中 MyRec.MyArr[0]:=5; // just for demonstration MyRec.Name:='Record 2'; MyRec.Completed:=false; MyList.Add(MyRec); 当将第一个项目添加到列表后MyRec.MyArr发生更改时,存储到列表中的MyArr也会更改.但是其他记录字段没有. 我的问题是如何防止MyRec.MyArr中的更改反映在已存储在列表项中的数组上. 我需要申报多条记录吗? 解决方法
此示例可以像这样简化,删除对泛型的所有引用:
{$APPTYPE CONSOLE} var x,y: array of Integer; begin SetLength(x,1); x[0] := 42; y := x; Writeln(x[0]); y[0] := 666; Writeln(x[0]); end. 输出是: 42 666 原因是动态数组是引用类型.分配给动态数组类型的变量时,您将获取另一个引用而不进行复制. 您可以通过强制引用是唯一的(这只是一个简单的引用)来解决这个问题.有很多方法可以实现这一目标.例如,您可以在要唯一的数组上调用SetLength. {$APPTYPE CONSOLE} var x,1); x[0] := 42; y := x; SetLength(y,Length(y)); Writeln(x[0]); y[0] := 666; Writeln(x[0]); end. 输出: 42 42 所以,在你的代码中,你可以像这样写: MyList:=TList<TMyRec>.Create; SetLength(MyRec.MyArr,5); MyRec.MyArr[0]:=8; // just for demonstration MyRec.Name:='Record 1'; MyRec.Completed:=true; MyList.Add(MyRec); SetLength(MyRec.MyArr,5); // <-- make the array unique MyRec.MyArr[0]:=5; // just for demonstration MyRec.Name:='Record 2'; MyRec.Completed:=false; MyList.Add(MyRec); 您可以使用各种其他方法来强制执行唯一性,包括Finalize,分配nil,Copy等. 这个问题在documentation中有详细介绍.以下是相关的摘录:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |