gpt4 book ai didi

delphi - 为什么 TFunc 可以正确遵循,但 TFunc 的数组 [0..1] 却不能?

转载 作者:行者123 更新时间:2023-12-03 15:49:56 25 4
gpt4 key购买 nike

如果我有一个 TFunc<T: class>该类型的变量将允许我直接取消引用类成员。
甚至类(class)完成也支持它。

enter image description here

如果我有一个数组 TFunc<T>那么这个就无法编译。
为什么不呢?这是编译器错误还是有一些根本原因?

program Project33;
{$APPTYPE CONSOLE}
uses
System.SysUtils;

type
TTestObject = class(TInterfacedObject, IInterface)
procedure Test;
end;

procedure TTestObject.Test;
begin
WriteLn('Test');
end;

procedure Test;
var
A: IInterface;
TestObject: array [0..4] of TFunc<TTestObject>;
SingleObject: TFunc<TTestObject>;
i: integer;
begin
for i:= 0 to 4 do begin
a:= TTestObject.Create;
TestObject[i]:= function: TTestObject
begin
Result:= a as TTestObject;
end;
TestObject[i].Test; //<<-- does not compile
SingleObject:= TestObject[i];
SingleObject.Test; // <<-- works.
end;
end;

begin
Test; ReadLn;
end.

最佳答案

Pascal 允许在调用没有参数的函数或过程时省略括号。在您的代码中 SingleObject 是一个函数,并且

SingleObject.Test

相当于

SingleObject().Test

这里有一个歧义。当解析器遇到 SingleObject 时,它必须决定是要引用该函数还是要调用它。解析器通过考虑上下文来解决这种歧义。在上面的示例中,它决定由于您使用了 . 运算符,因此您必须打算调用该函数,然后将 . 运算符应用于该值从该函数调用返回。

现在,对于您的数组示例,解析器似乎无法消除歧义。我个人认为这是一个疏忽。据我所知,完全有可能消除歧义。

考虑这个程序:

type
TRec = class
procedure Foo; virtual; abstract;
end;

TFunc = function: TRec;
TFuncOfObj = function: TRec of object;
TRefFunc = reference to function: TRec;

var
ScalarFunc: TFunc;
ArrFunc: array [0..0] of TFunc;
ScalarFuncOfObj: TFuncOfObj;
ArrFuncOfObj: array [0..0] of TFuncOfObj;
ScalarRefFunc: TRefFunc;
ArrRefFunc: array [0..0] of TRefFunc;

begin
ScalarFunc.Foo; // fine
ArrFunc[0].Foo; // fine
ScalarFuncOfObj.Foo; // fine
ArrFuncOfObj[0].Foo; // fine
ScalarRefFunc.Foo; // fine
ArrRefFunc[0].Foo; // E2003 Undeclared identifier: 'Foo'
end.

如您所见,只有引用函数的数组存在问题。我怀疑编译器开发人员在添加对引用函数类型的支持时错过了处理这种消歧所需的任何步骤。

解决方法很简单。您需要明确消除歧义:

ArrRefFunc[0]().Foo;

整个问题源于 Pascal 中允许在函数没有参数时省略函数调用括号的决定。在我看来,考虑到现代编程风格所出现的模糊性问题,最好回到过去并改变这个决定。

关于delphi - 为什么 TFunc<T> 可以正确遵循,但 TFunc<T> 的数组 [0..1] 却不能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30157034/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com