加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

arrays – 包含动态数组的记录的通用列表

发布时间:2020-12-15 09:20:58 所属栏目:大数据 来源:网络整理
导读:我有一个通用的记录列表.这些记录包含如下的动态数组 Type TMyRec=recordMyArr:Array of Integer; Name: string; Completed: Boolean; end;var MyList:TListTMyRec; MyRec:TMyRec; 然后我创建列表并设置数组长度,如下所示 MyList:=TListTMyRec.Create;SetLen
我有一个通用的记录列表.这些记录包含如下的动态数组

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中有详细介绍.以下是相关的摘录:

If X and Y are variables of the same dynamic-array type,X := Y points
X to the same array as Y. (There is no need to allocate memory for X
before performing this operation.) Unlike strings and static arrays,
copy-on-write is not employed for dynamic arrays,so they are not
automatically copied before they are written to. For example,after
this code executes:

06005

the value of A[0] is 2. (If A and B were static arrays,A[0] would
still be 1.) Assigning to a dynamic-array index (for example,
MyFlexibleArray[2] := 7) does not reallocate the array. Out-of-range
indexes are not reported at compile time. In contrast,to make an
independent copy of a dynamic array,you must use the global Copy
function:

06006

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读