我在看 Delphi:char和tchararray阵列“不兼容类型” 并开始实验。我发现的很有趣。

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.

这个简单的小示例显示了如何使用开放阵列参数将动态数组传递到过程。它编译并完全按预期运行。

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'

为什么会这?

搜索一段时间后,我发现了 QC报告。我正在运行Delphi 2009,但仍在发生。

有帮助吗?

解决方案

由于该文档专门提及类型char的开放数组参数与动态数组兼容,因此这应该是一个错误。从 “打开数组参数”:

function Find(A: array of Char):整数;
[...]
笔记: ...]上一个示例创建一个函数,该函数采用任何字符元素,包括(但不限于)动态数组。 [...

其他提示

您可以使用这种数组,定义自己的类型:

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可以将PCHAR类型化为字符串。

我认为原因是 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 Kelly) 或者 丹尼·索普(Danny Thorpe) 将启动并为此提供更多反馈。

- 杰罗恩

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top