数组类型赋值如何工作?

Mar*_*unu 3 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;
Run Code Online (Sandbox Code Playgroud)

我想知道我是否已经正确完成了分配SwapItemLists.分配Items到时会发生tmp什么?是否会创建一个新的副本Items或者只传递该变量的指针?

Dav*_*nan 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]);
Run Code Online (Sandbox Code Playgroud)

在这段代码中,只有一个数组.这两个变量a,并b指的是阵列的同一个实例.

要制作动态数组的副本,请使用本机中的Copy功能System.

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

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