点在这里是唯一的。
现在:
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;
我想要实现的目标:
Function TSomeClass.GetPacket: TBytes;
begin
Result := DataWrite;
end;
因为Delphi中的数组是指向第一个元素的指针,后者只能写入4个字节,所以它的速度要快得多。这是对的吗?
答案 0 :(得分:7)
您需要注意的一点是,与字符串不同,动态数组不是“写时复制”。
如果指定字符串或动态数组,则只复制堆上数据的指针并增加引用计数。
但是使用字符串,如果你然后写入一个字符串(例如s [1]:='a'),其引用计数> 1,编译器将发出代码,确保首先复制字符串。动态数组不是这种情况:
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!
因此,对于您的代码,如果在调用GetPacket后更改DataWrite的内容,则更改将在GetPacket返回的TBytes中可见。
对于实际制作数组副本的代码,您可以使用:
而不是调用SetLength And Move。function TSomeClass.GetPacket: TBytes;
begin
Result := Copy(DataWrite, 0, High(Integer));
end;
答案 1 :(得分:2)
这将有效,但请注意,您现在正在调用GetPacket
的客户端代码中的相同字节数组。这可能是一个坏主意。考虑一些网络库,它对字节数组进行一些额外的压缩或加密。这会产生很多可能与你的类进行交互而不使用暴露的接口 - 这很糟糕。因此,恕我直言复制是更好的选择。
BTW:我们在这里谈论的数组有多大?