【问题标题】:Is it possible to initialize a constant array of reference to function?是否可以初始化函数引用的常量数组?
【发布时间】:2018-06-27 09:43:58
【问题描述】:

在阅读了 Embarcadero 关于 procedural typesanonymous methodsDavid Heffernan's explanation 的文档后,我仍然不太明白为什么编译器禁止初始化函数引用的常量数组,如下例中的 C_BAR。

program MyProgram;

{$APPTYPE CONSOLE}

{$R *.res}

type
  TFoo = function: Integer;
  TBar = reference to function: Integer;

  function FooBar: Integer;
  begin
    Result := 42;
  end;

const
  // This works
  C_FOO: array[0..0] of TFoo = (FooBar);

  // These lines do not compile
  // C_BAR: array[0..0] of TBar = (FooBar); // TBar incompatible with Integer
  // C_BAR: array[0..0] of TBar = (@FooBar); // TBar incompatible with Pointer

var
  Foo: array[0..0] of TFoo;
  Bar: array[0..0] of TBar;
begin
  Foo[0] := FooBar; // Foo[0] = MyProgram.FooBar
  Bar[0] := FooBar; // Bar[0] = MyProgram$1$ActRec($1CC8CF0) as TBar

  Foo[0] := C_FOO[0]; // Foo[0] = MyProgram.FooBar
  Bar[0] := C_FOO[0]; // Bar[0] = MyProgram$1$ActRec($1CC8CF0) as TBar
end.

使用调试器,我可以看到 Bar[0] 等于某个地址(我认为?),这告诉我在我的理解背后发生了一些事情......

那么在我的示例中是否可以初始化像 C_BAR 这样的常量数组?如果是,怎么做,否则,为什么?

【问题讨论】:

    标签: delphi delphi-10.1-berlin


    【解决方案1】:

    相关文档在Typed Constants 部分:

    类型化的常量,不像真正的常量,可以保存数组的值, 记录、过程和指针类型。类型化的常量不能出现在 常量表达式。

    像这样声明一个类型化的常量:

    const identifier: type = value
    

    其中 identifier 是任何有效的标识符,type 是任何类型,除了 文件和变体,而 value 是类型的表达式。例如,

    const Max: Integer = 100;
    

    在大多数情况下,value 必须是一个常量表达式;但如果类型是 数组、记录、过程或指针类型,适用特殊规则。

    程序类型的那些特殊规则如下:

    要声明过程常量,请指定函数名或 与声明的常量类型兼容的过程。 例如,

    function Calc(X, Y: Integer): Integer;
    begin
      ...
    end;
    type TFunction = function(X, Y: Integer): Integer;
    const MyFunction: TFunction = Calc;
    

    鉴于这些声明,您可以使用过程常量 函数调用中的 MyFunction:

    I := MyFunction(5, 7)
    

    您还可以将值 nil 分配给过程常量。

    这就解释了为什么可以使用TFoo 声明类型常量。

    至于匿名方法,它们没有在本文档的任何地方列出。现在,匿名方法被实现为接口。该接口有一个由编译器生成的支持类,因此需要创建该类的一个实例。该实例是在堆上分配的,这(至少是一个原因)为什么不能将匿名方法声明为常量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-10
      • 1970-01-01
      • 2014-07-26
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 2016-03-03
      相关资源
      最近更新 更多