在Delphi中将TBytes数据正确地复制到Byte数组的方法

8

假设有以下内容:

LBytes: TBytes;
LArr: array[1..512] of Byte;
...
SetLength(LBytes, 512);

什么是正确的Move()调用,将所有字节从LBytes复制到LArr?
Move(LBytes[0], LArr, Length(LBytes)); // works

Move(LBytes[0], LArr[1], Length(LBytes)); // works, too

Move(LBytes, LArr[1], Length(LBytes)); // fail

有人可以解释一下,为什么使用Larr和Larr[1]没有区别,但是使用LBytes[0]和LBytes有区别吗?


LBytes -> 指向 TBytes 的指针,LBytes[0] 指向第一个元素。LArr 是一个固定大小的数组,因此 LArr 和 LArr[1] 是相同的(例如指向第一个元素)。前两个因此是正确的。请使用您认为最易读的方式。 - Ritsaert Hornstra
1个回答

12

有人能解释一下为什么使用 Larr 和 Larr1 没有区别,但使用 LBytes[0] 和 LBytes 有区别吗?

这是因为 LBytes 是一个动态数组,最终是指向数组的指针。而 LArr 则是数组本身。

换句话说,动态数组是引用类型,而固定长度数组是值类型。

在我的书中,有两种可行的方法来做到这一点:

Assert(Length(LBytes)<=Length(LArr));
Move(LBytes[0], LArr, Length(LBytes));

或者

Assert(Length(LBytes)<=Length(LArr));
Move(Pointer(LBytes)^, LArr, Length(LBytes));

我更喜欢后者,因为当启用范围检查时,它对零长度数组具有弹性。在这种情况下,第一个代码块会导致运行时范围检查错误。
你可能也希望避免这种低级技巧。我有一个实用类(实用类),让我可以这样写:
TArray.Move<Byte>(LBytes, LArr);

该方法的签名是:
class procedure Move<T>(const Source: array of T; var Dest: array of T); overload; static;

我喜欢实用类Move<T>。这个单元可用吗? - Ritsaert Hornstra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接