我看着Delphi: array of Char and TCharArray "Incompatible Types"并开始尝试。我发现的很有趣。
procedure Clear(AArray: array of Integer);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := 0;
end;
var
MyArray: array of Integer;
begin
Clear(MyArray);
end.
这个简单的小例子展示了如何使用Open Array参数将动态数组传递给过程。它完全按预期编译和运行。
procedure Clear(AArray: array of Char);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := #0;
end;
var
MyArray: array of Char;
begin
Clear(MyArray);
end.
这是几乎相同的代码,唯一的区别是使用Char
而不是Integer
的数组。它不编译。相反,编译器会吐出:
E2010 Incompatible types: 'Array' and 'Dynamic array'
为什么会这样?
在搜索了一段时间后,我发现了this QC报告。我正在运行Delphi 2009并且它仍在发生。
答案 0 :(得分:4)
由于文档特别提到Char类型的开放数组参数与动态数组兼容,这应该是一个bug。来自'Open Array Parameters':
function Find(A: array of Char):
整数;
[...]
注: [...] 上一个示例创建一个函数 采用任何Char元素数组, 包括(但不限于)动态 阵列。 [...]
答案 1 :(得分:4)
您可以使用这种数组,定义自己的类型:
type
TCharDynArray = array of char;
procedure Clear(AArray: TCharDynArray);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := #0;
end;
procedure test;
var
MyArray: TCharDynArray;
begin
Clear(MyArray);
end;
此代码编译正常。当然它没有做任何有用的事情(AArray参数没有设置为“var”,因此在为每个项目分配#0之前将它复制到堆栈上)。但至少,它会编译。
实际上,我发现更容易为动态数组定义或使用高级类型(如TIntegerDynArray),因为至少它允许你使用var传递数组作为引用,因此避免制作一个复制堆栈,让你的代码更快。
关于到PChar的映射,通常用于所有动态数组:您可以将TIntegerDynArray映射到指针,然后将其用作PInteger或PIntegerArray:
procedure AddInteger(var Values: TIntegerDynArray; Value: integer);
var n: integer;
begin
n := Length(Values);
SetLength(Values,n+1);
Values[n] := Value;
end;
procedure Loop(V: PInteger);
begin
if V<>nil then
while V^<>0 do begin
write(V^,' ');
inc(V); // go to next integer in array
end;
end;
var IntArray: TIntegerDynArray;
begin
Loop(pointer(IntArray)); // will display nothing, since pointer(IntArray)=nil for IntArray=[]
AddInteger(IntArray,2);
AddInteger(IntArray,3);
AddInteger(IntArray,0);
Loop(pointer(IntArray)); // will display '2 3 '
end.
问题是与“数组整数”不一致的“char数组”代码肯定在编译器内在函数中,并且PChar可以被类型转换为字符串。
答案 2 :(得分:2)
我认为原因是array of Char
与PChar
兼容,因为此代码会编译:
procedure Clear(AArray: array of Char);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := #0;
end;
var
MyArray: array of Char;
P: PChar;
begin
Clear(P^);
end.
这可能是出于历史原因 希望Barry Kelly或Danny Thorpe能够启动并提供更多反馈。
- 的Jeroen