Arrays Delphi:Char和TCharArray数组;“不兼容类型”;

Arrays Delphi:Char和TCharArray数组;“不兼容类型”;,arrays,delphi,types,char,Arrays,Delphi,Types,Char,我曾在下面的评论中遇到过几次“不兼容类型”错误,对于Delphi 2007不直接支持这一错误,我从未感到满意: program Project1; {$APPTYPE CONSOLE} type TCharArray = array of Char; procedure DoArray(Chars: array of Char); begin end; function ReturnTCharArray: TCharArray; var CharArray: TCharArray; beg

我曾在下面的评论中遇到过几次“不兼容类型”错误,对于Delphi 2007不直接支持这一错误,我从未感到满意:

program Project1; {$APPTYPE CONSOLE}

type TCharArray = array of Char;

procedure DoArray(Chars: array of Char);
begin
end;

function ReturnTCharArray: TCharArray;
var CharArray: TCharArray;
begin
  Result := CharArray;
end;

begin
  DoArray(ReturnTCharArray); // [DCC Error] Project1.dpr(18): E2010 Incompatible types: 'Array' and 'TCharArray'
end.

难道不可能使一个数组类型“别名”与另一个数组类型相互兼容吗?假设我不能更改DoArray的声明(它是第三方库的一部分),那么如何编写一个返回与DoArray的param兼容的char数组的函数?简单的“函数ReturnAChar:array of Char;”会导致“预期标识符,但找到“array”错误。我甚至尝试将返回数组的函数更改为带有var“array of Char”pram的过程,但这也不允许在过程中设置“array of Char”参数的长度(“Constant object不能作为var参数传递”)。

不允许。Pascal通过名称而不是描述来处理数组类型,并且始终具有。你为什么不能更改DoArray的声明?(为什么一开始它是这样写的?

当关闭时,编译器不会检查分配给指针的内容,因此可以使用错误的参数调用过程:

program Project1; {$APPTYPE CONSOLE}

type TCharArray = array of Char;

procedure DoArray(Chars: array of Char);
begin
end;

function ReturnTCharArray: TCharArray;
var CharArray: TCharArray;
begin
  Result := CharArray;
end;

type TFakeDoArray = procedure(Chars: TCharArray);

var
  FakeDoArray: TFakeDoArray;
begin
  FakeDoArray := @DoArray;
  FakeDoArray(ReturnTCharArray);
end.
尽管编译器不会抱怨,但由于“Jeroen”在其评论中指出的原因,这将不起作用

然后,您可以尝试声明伪过程与具有开放数组参数的伪过程兼容:

program Project1; {$APPTYPE CONSOLE}

type TCharArray = array of Char;

procedure DoArray(Chars: array of Char);
begin
end;

function ReturnTCharArray: TCharArray;
var CharArray: TCharArray;
begin
  Result := CharArray;
end;

type
  TFakeDoArray = procedure(AnArray: Pointer; High: Integer);

var
  FakeDoArray: TFakeDoArray;
  Tmp: TCharArray;
begin
  FakeDoArray := @DoArray;
  Tmp := ReturnTCharArray;
  FakeDoArray(Tmp, High(Tmp));
end.
鲁迪的工作值得表扬。以及相关文件(来自):

打开的数组参数作为 两个32位值。第一个值是 指向数组数据的指针,以及 第二个值比 数组中的元素数


有一点我还没有提到,TCharArray是一种动态数组类型,而

procedure DoArray(Chars: array of Char); 
Chars是一个开放数组参数。没有用于声明动态数组参数的语法。要拥有动态数组参数,需要将其声明为类型

type
  TMyDynArray = array of Integer;

procedure DoArray(Integers : TMyDynArray);

这实际上可能是一个编译器错误(或一个从未正确记录的限制)。我做了一些实验,发现您可以将一个动态数组(类型化或非类型化)传递给一个几乎所有类型都需要一个开放数组的过程。。。除了Char和WideChar


有关问题的说明和可能的解决方法,请参阅。

+1;正确的!(哦,顺便说一句:还有“开放数组”和“类型数组”的区别,这可能是Anagoge接下来要遇到的问题)DoArray是第三方库的一部分,我不想(实际上也不能)编辑它。我可以理解,您有时希望通过名称来实现类型的类型安全性,但这种语言限制对我来说更烦人,而不是更有用。难道没有办法说服Delphi从函数返回一个文字/精确的“字符数组”吗?这似乎是一个相当基本的要求。@Anagoge:不,据我所知没有。我想这就是为什么他们在Delphi 2009中添加了
TArray
TArray
被定义为T的数组,但由于它现在是一种命名类型,所以它回避了所有这些问题。这个答案偏离了一点。DoArray接受开放数组。@Rudy这是一个编译器错误。这不应该是投票最多的答案。这里的社区精神就是否决这一点。出于某种原因,我一直认为动态数组和开放数组是不兼容的。。。我真的很惊讶只有char和Widechar是。看起来他们参与了我早期的Delphi阵列实验,我再也没有回去过。或者可能是在Delphi5中?@Ken文档声称开放数组参数可以处理任何相同类型的数组。所以我同样感到惊讶的是,Char数组和WideChar数组没有编译。@KennethCochran:它应该接受任何数组,甚至Char/WideChar数组。这是不正确的。任何形式的数组都可以传递给开放数组参数。编译器拒绝这是因为编译器有缺陷。在这个答案中,我在哪里提到动态数组不能作为开放数组参数传递?我只提到作为一个参数的char
array
并没有使参数成为一个动态数组,而是一个开放数组。由于问题抱怨他不能在DoArray函数中使用“SetLength”,这表明他想要的不是开放数组参数。那necro呢?