3

使用 D2010,我想做这样的事情:

procedure SizeArray(var aArr: array of integer; aSize: integer);
begin
  SetLength(aArr,aSize);
end;

但这无法编译。因为我的“aArr”参数不是动态数组,它是一个开放数组参数。并且不能在其上调用 SetLength。我知道强制参数成为动态数组的唯一方法是给它一个类型名称,如下所示:

type
  TIntArray = array of integer;

procedure SizeArray(var aArr: TIntArray; aSize: integer);
begin
  SetLength(aArr,aSize);
end;

现在代码编译了。在大多数情况下它工作正常,但这失败了:

procedure Test;
var
  a : array of integer;
begin
  SizeArray(a,5);
end;

因为实际和正式 var 参数的类型必须相同,并且编译器不会将“整数数组”和“TIntArray”识别为相同类型。

所以,这是我的问题:有什么方法可以让编译器将我的 var 参数识别为动态数组而不是开放数组,以便调用者可以声明一个简单的“整数数组”而不是一些命名类型?

提前致谢。

4

3 回答 3

10

Pascal 以及 Delphi 的扩展对数组类型(包括动态数组)使用名称等价而不是结构等价。使用没有名称的类型声明的变量,如下所示:

var
  x: array of Integer;

...最终使用一个不等同于任何其他类型名称的匿名名称。这就是你得到错误的原因。该错误可能很有用;例如,考虑一个数组Kilometers与一个数组Kilograms- 但通常情况下,为每个不同类型声明一个名称是不方便的。

为了解决这个问题,并保持在安全类型系统中(因此避免使用无类型参数,正如 skamradt 建议的那样),我建议对每个特定的数组形状使用相同的名称。TArray<T>您可以通过使用在 System 单元中声明的类型在相当大的程度上做到这一点。因此,不要使用 ,而是array of Integer使用TArray<Integer>

TArray<T>声明如下:

type
  TArray<T> = array of T;

...因此它可以为任意动态数组提供名称。

于 2009-10-30T22:07:52.020 回答
9

这确实是可能的......只需使用绝对关键字和无类型变量。

procedure SizeArray(var aArr; aSize: integer);
var
  ActArr : Array of Integer absolute aArr;
begin
  SetLength(ActArr,aSize);
end;

var
  Test : Array of Integer;
begin
  SizeArray(Test,5);
  showMessage(IntTostr(High(Test)));  // -- returns 4
end;
于 2009-10-30T21:55:55.473 回答
0

不,没有办法做到这一点。它是 Pascal 语言规范的一部分,不太可能改变。

编辑:Skamradt 找到了一种方法。让我重申一下。没有办法安全地做到这一点。

于 2009-10-30T21:35:24.617 回答