数组类型赋值如何工作?

时间:2014-12-02 15:04:59

标签: arrays delphi variable-assignment

我有以下代码:

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的新副本,还是只传递该变量的指针?

1 个答案:

答案 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]);

在此代码中,只有一个数组。变量ab都引用该数组的相同实例。

要制作动态数组的副本,请使用System单元中的Copy功能。

引用类型的其他示例包括类实例变量,接口变量,匿名方法和字符串。这些都与动态数组类似,但字符串除外。

字符串实现了写时复制。这意味着如果字符串对象具有多个引用,则通过引用的修改将导致在修改时进行复制。这具有使字符串数据类型在语义上像值类型一样的效果。实际上,当您使用带有字符串的赋值时,该赋值在语义上与复制无法区分。但是,复制字符串的实际实现被推迟到需要时,作为优化。