当参数类型是Char的数组打开时,是否允许动态数组Char?

时间:2010-09-23 19:05:37

标签: delphi dynamic-arrays open-array-parameters

我看着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并且它仍在发生。

3 个答案:

答案 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 CharPChar兼容,因为此代码会编译:

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 KellyDanny Thorpe能够启动并提供更多反馈。

- 的Jeroen