为什么我不能将字节数组传递给采用 TByteDynArray 的例程?

Why can't I pass an array of bytes to a routine that takes TByteDynArray?

文档将 System.Types.TByteDynArray 定义为:

type TByteDynArray = array of Byte;

如果我像这样创建一个例程:

procedure DoSomething(args: array of Byte);
begin
end;

这样调用例程,没有编译错误:

DoSomething([1, 2, 3]);

但是,如果我将例程采用的类型更改为:

procedure DoSomething(args: TByteDynArray);

以相同方式调用函数会产生此编译错误:

[DCC Error] E2010 Incompatible types: 'TByteDynArray' and 'Set'

为什么 array of ByteTByteDynArray 没有受到平等对待,显然他们应该受到平等对待?我的代码库大量引用 TByteDynArray,我想使用这个方便的速记来创建这样的数组,而不是 TByteDynArray.Create(1, 2, 3)

尽管语法看起来相同,但您在这里处理的是两件事。

一种叫做动态数组类型:type TByteDynArray = array of Byte;和 另一个是开数组参数procedure DoSomething(args: array of Byte);

Open array parameter 允许将给定类型的任何数组传递给过程,包括动态数组。

但是当你声明procedure DoSomething(args: TByteDynArray);时你只能传递TByteDynArray变量给它。

[1, 2, 3] 是静态数组,它的赋值与动态数组不兼容。

下面的赋值会抛出同样的错误

var
  a: TByteDynArray;

a := [1, 2, 3];

在 Delphi [] 中也用于声明集合,因此编译器认为您正在尝试将集合分配给动态数组。

var
  s: set of byte;

  s := [1, 2, 3];

您可以使用 isas 运算符进行转换和检查。可以使用一些隐式转换,但编译器会警告您。这是长运行中Delphi的一个优点。它可以让你做那些事情,但它不会让你用几乎——但不完全——一样的东西愉快地搬起石头砸自己的脚,除非你明确要求。

这是Delphi试图让愚蠢变得难以(呃)的方法之一。学会用那个安全带开车。没有那么痛,而且安全很多。