type
TStringArray = array of string;
var
a: TStringArray;
//...and somewhere else
var
b: TStringArray;
然后你可以做:
a := Copy(b, Low(b), Length(b)); //really clean, but unnecessary
//...or
a := Copy(b, 0, MaxInt); //dynamic arrays always have zero low bound
//and Copy copies only "up to" Count items
var A,B: array[0..10] of integer;
DA, DB: array of double;
i: integer;
begin
for i := low(A) to high(A) do
A[i] := i;
move(A[0],B[0],length(A)*sizeof(A[0])); // first version, compiler does the stuff
move(A[0],B[0],sizeof(A)); // it works
move(A[0],B[0],40); // if you know what you're doing, since sizeof(A)=40
SetLength(DA,10); // DA[0]..DA[9]
for i := 0 to high(DA) do // or for i := 0 to 9 if you know what you're doing
DA[i] :=
SetLength(DB,length(DA));
if length(DA)<=length(DB) then // if your dynamic array may be void, use this before to avoid GPF
move(DA[0],DB[0],length(DA)*sizeof(DA[0]));
if pointer(DA)<>nil then // this will just check that DA[] is not void
move(pointer(DA)^,pointer(DB)^,length(DA)*sizeof(double)); // similar to previous
end;
2-如果你的数组包含字符串或其他引用内容数组,你必须使用循环:
var A,B: array[0..10] of string;
i: integer;
begin
for i := 0 to high(A) do
A[i] := IntToStr(i);
for i := 0 to high(A) do
B[i] := A[i]; // this doesn't copy the string content, just add a reference count to every A[], and copy a pointer: it's very fast indeed.
end;
TGen = record // Unused record to allow generic functions.
public
...
class function arrayCopy<T>(const a: array of T): TArray<T>; static;
end;
class function TGen.arrayCopy<T>(const a: array of T): TArray<T>;
var i: integer;
begin
SetLength(result, length(a));
for i := Low(a) to High(a) do
result[i] := a[i];
end;
5条答案
按热度按时间qcbq4gxm1#
为了安全起见,在动态数组上使用
Copy
函数,因为它在内部处理托管类型。数组必须是相同的类型,即在同一表达式中声明:或者通过定义自定义数组类型:
然后你可以做:
在静态数组和混合数组类型时,必须使用循环(我不建议这样做)。
如果你真的必须使用
Move
,请记住检查零长度,因为A[0]
结构可能会引发范围检查错误(SizeOf(A[0])
是一个值得注意的例外,它由编译器魔法处理,并且从未实际执行)。另外,* 永远不要 * 假设
A = A[0]
或SizeOf(A) = Length(A) * SizeOf(A[0])
,因为这只适用于静态数组,如果你以后试图将巨大的代码库重构为动态数组,它会给你带来严重的影响。r9f1avp52#
对于动态数组:
在动态数组中,赋值语句只复制对数组的引用,而SetLength执行物理复制/复制它的工作,留下两个单独的、独立的动态数组。
qaxu7uf23#
参见article on delphibasics.co.uk
您可以使用Copy方法复制数组(传入0作为索引,传入Length(Source)作为计数以复制完整内容)。
不要对string/array/interface/etc托管类型的数组使用Move或CopyMemory。这样做将绕过 Delphi 的引用计数机制,并将导致内存泄漏和数据损坏。
tvokkenx4#
1-如果你的数组不包含任何字符串或动态数组,你可以使用move,但动态数组不能像固定大小的数组那样处理:
2-如果你的数组包含字符串或其他引用内容数组,你必须使用循环:
pqwbnv8z5#
你可以使用一个记录类型,它使用一个泛型函数将数组复制到一个动态的TArray变量,我已经开始使用了:
给定一个表单变量
和从枚举类型上的数组分配的参数
你可以初始化表单变量: