Delphi TBytes - 如何复制?

JBA*_*JBA 2 arrays delphi

点是这里的优化.

现在:

type TSomeClass=class(TObject)
  private
    DataWrite: TBytes;
  ...
end;

Function TSomeClass.GetPacket: TBytes;
begin
  SetLength(Result, Length(DataWrite));
  Move(DataWrite[0],Result[0],Length(DataWrite));
end;
Run Code Online (Sandbox Code Playgroud)

我想要实现的目标:

Function TSomeClass.GetPacket: TBytes;
begin
  Result := DataWrite;
end;
Run Code Online (Sandbox Code Playgroud)

因为Delphi中的数组是指向第一个元素的指针,后者只能写入4个字节,所以它的速度要快得多.它是否正确?

Tho*_*ler 7

您需要注意的一件事是,与字符串不同,动态数组不是"写时复制".

如果指定字符串或动态数组,则仅复制堆上数据的指针并增加引用计数.

但是使用字符串,如果然后写入一个引用计数> 1的字符串(例如s [1]:='a'),编译器将发出代码以确保首先复制字符串.动态数组不是这种情况:

var 
  s, t: string;
  a, b: TBytes;
begin
  s := 'abc';
  t := s;
  t[2] := 'X';
  WriteLn(s); //still abc

  a := TBytes.Create(1, 2, 3);
  b := a;
  b[1] := 0;
  WriteLn(a[1]); // is now 0 not 2!
Run Code Online (Sandbox Code Playgroud)

因此,对于您的代码,如果在调用GetPacket后更改DataWrite的内容,则更改将在GetPacket返回的TBytes中可见.

对于实际制作数组副本的代码,您可以使用以下命令而不是调用SetLength And Move;

function TSomeClass.GetPacket: TBytes;
begin
  Result := Copy(DataWrite, 0, High(Integer));
end;
Run Code Online (Sandbox Code Playgroud)