我有以下代码:
type
PSuperListItem = ^TSuperListItem;
TSuperListItem = record
SubItems : array of String;
Marked : Boolean;
ImageIndex: Integer;
end;
TSuperListItems = array of PSuperListItem;
TMyList = class(TCustomControl)
public
Items, ItemsX : TSuperListItems;
procedure SwapItemLists;
end;
procedure TMyList.SwapItemLists;
var tmp:TSuperListItems;
begin
tmp:=Items; Items:=ItemsX; ItemsX:=tmp;
end;
我想知道我是否正确完成了SwapItemLists
的分配。将Items
分配给tmp
时会发生什么?将创建Items
的新副本,还是只传递该变量的指针?
答案 0 :(得分:8)
动态数组是引用类型。这意味着您只需交换引用。不复制数组的内容。
能够自己回答这类问题的关键是理解作为参考类型意味着什么。在动态数组的情况下,动态数组类型的变量保存对数组的引用。这是在幕后通过动态数组变量实现的,该变量是指向数组的指针。
考虑以下代码:
var
a, b: TArray<Integer>;
....
a := TArray<Integer>.Create(42);
b := a;
b[0] := 666;
Assert(a[0] = 666);
Assert(@a[0] = @b[0]);
在此代码中,只有一个数组。变量a
和b
都引用该数组的相同实例。
要制作动态数组的副本,请使用System
单元中的Copy
功能。
引用类型的其他示例包括类实例变量,接口变量,匿名方法和字符串。这些都与动态数组类似,但字符串除外。
字符串实现了写时复制。这意味着如果字符串对象具有多个引用,则通过引用的修改将导致在修改时进行复制。这具有使字符串数据类型在语义上像值类型一样的效果。实际上,当您使用带有字符串的赋值时,该赋值在语义上与复制无法区分。但是,复制字符串的实际实现被推迟到需要时,作为优化。