Arrays 数组类型分配是如何工作的?

Arrays 数组类型分配是如何工作的?,arrays,delphi,variable-assignment,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) pu

我有以下代码:

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
中的分配。当我将
项目分配给
tmp
时会发生什么?将创建
项的新副本
或仅传递该变量的指针?

动态数组是引用类型。这意味着您只是交换了引用。数组的内容不会被复制

能够自己回答这类问题的关键是理解引用类型的含义。对于动态数组,动态数组类型的变量保存对数组的引用。这是通过动态数组变量作为数组指针在后台实现的

考虑以下代码:

var
  a, b: TArray<Integer>;
....
a := TArray<Integer>.Create(42);
b := a;
b[0] := 666;
Assert(a[0] = 666);
Assert(@a[0] = @b[0]);
var
a、 b:焦油;
....
a:=TArray.Create(42);
b:=a;
b[0]:=666;
断言(a[0]=666);
断言(@a[0]=@b[0]);
在这段代码中,只有一个数组。变量
a
b
都引用该数组的同一实例

要复制动态阵列,请使用
系统中的功能

引用类型的其他示例包括类实例变量、接口变量、匿名方法和字符串。除了字符串之外,它们的行为都类似于动态数组


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

动态数组是引用类型。这意味着您只是交换了引用。数组的内容不会被复制

能够自己回答这类问题的关键是理解引用类型的含义。对于动态数组,动态数组类型的变量保存对数组的引用。这是通过动态数组变量作为数组指针在后台实现的

考虑以下代码:

var
  a, b: TArray<Integer>;
....
a := TArray<Integer>.Create(42);
b := a;
b[0] := 666;
Assert(a[0] = 666);
Assert(@a[0] = @b[0]);
var
a、 b:焦油;
....
a:=TArray.Create(42);
b:=a;
b[0]:=666;
断言(a[0]=666);
断言(@a[0]=@b[0]);
在这段代码中,只有一个数组。变量
a
b
都引用该数组的同一实例

要复制动态阵列,请使用
系统中的功能

引用类型的其他示例包括类实例变量、接口变量、匿名方法和字符串。除了字符串之外,它们的行为都类似于动态数组


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

可能是吹毛求疵,但我认为你关于字符串赋值的陈述可能会让未来的读者感到困惑:你说赋值是通过复制字符串来执行的,然后你继续说复制会推迟到需要的时候。因此,未来的读者可能会想知道字符串何时被真正复制。@iamjoosy Fair point。我试着换个词。我想说的是,从程序员的角度来看,字符串的行为就好像它们是值一样,但实现是对COW的引用。从广义上讲,你不需要了解实现,如果你把字符串当作是值来处理,那么你的心理模型就会与行为相匹配。也许是吹毛求疵,但我认为你关于字符串赋值的陈述可能会让未来的读者感到困惑:你说赋值是通过复制字符串来执行的,然后你继续说复制会推迟到需要的时候。因此,未来的读者可能会想知道字符串何时被真正复制。@iamjoosy Fair point。我试着换个词。我想说的是,从程序员的角度来看,字符串的行为就好像它们是值一样,但实现是对COW的引用。从广义上讲,您不需要了解实现,如果您将字符串看作是值,那么您的心智模型将匹配行为。