Function 如何将另一个函数返回的函数赋值给函数变量?结果而不是生成函数本身

Function 如何将另一个函数返回的函数赋值给函数变量?结果而不是生成函数本身,function,delphi,variables,function-pointers,anonymous-methods,Function,Delphi,Variables,Function Pointers,Anonymous Methods,函数正在返回匿名函数。我想将结果分配给一个变量。然而,编译器认为我试图分配函数,而不是函数的结果。我如何解决这个问题 program Project9; {$APPTYPE CONSOLE} type TMyEvent = reference to function: string; var v1: TMyEvent; function GetHandler: TMyEvent; begin Result := function: string beg

函数正在返回匿名函数。我想将结果分配给一个变量。然而,编译器认为我试图分配函数,而不是函数的结果。我如何解决这个问题

program Project9;

{$APPTYPE CONSOLE}

type
  TMyEvent = reference to function: string;

var
  v1: TMyEvent;

function GetHandler: TMyEvent;
begin
  Result := function: string
            begin
              Result := '';
            end;
end;

begin
  v1 := GetHandler;  // <- Incompatible types: 'TMyEvent' and 'Procedure'
end.
程序项目9;
{$APPTYPE控制台}
类型
TMyEvent=对函数的引用:字符串;
变量
v1:TMyEvent;
函数GetHandler:TMyEvent;
开始
结果:=函数:字符串
开始
结果:='';
结束;
结束;
开始

v1:=GetHandler;// 如果匿名方法/函数是无参数的,则必须使用()赋值


如果没有括号,Delphi将尝试将函数分配给变量。paren告诉它调用函数并将函数结果分配给变量。

Delphi的函数调用语法与大多数其他语言略有不同。在大多数语言中,为了调用函数,必须在函数名后使用parens
()
,通常称为函数调用运算符。如果函数只是命名的,并且没有提供参数,则该表达式将在不调用调用的情况下对函数求值

>以C++语言为例,

i = foo();
调用函数并将返回值存储在
i

另一方面,

fn = foo;
将函数地址存储在函数指针变量
fn

Delphi与此不同,对于无参数函数,允许您省略参数,但仍然调用函数。因此,在Delphi中,可以编写上面的第一行代码

i := foo;
这将调用函数

有点棘手的是,如果函数返回类型是过程类型、方法或匿名方法,正如您所发现的那样

在您的场景中

v1 := GetHandler;
在编译器的眼中是不明确的。由于
v1
是一个类型为匿名方法的变量,因此当省略paren时,编译器永远不会生成调用。如果它确实生成了一个调用,那么您将无法简单地将函数赋值给过程类型变量

>编译器将转换为在C++语言中发现的行为。如果希望调用函数,则必须提供参数。要使代码编译并工作,请编写

v1 := GetHandler();
报告对这一问题作了一些详细介绍。关键摘录如下:

在赋值语句中,左侧变量的类型决定了右侧过程或方法指针的解释


现在,通过判断,我发现一个表达的上下文可以决定其解释的想法相当令人不安。这一切都源于允许在省略paren时进行函数调用。我宁愿总是使用paren,从而避免上面讨论的歧义。特别是,这将允许表达意义独立于上下文

为了理解我的意思,我们回到我最初的例子。现在让我们更具体地说明所涉及的类型:

type
  TIntFunc = function: Integer;

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

var
  i: Integer;
  fn: TIntFunc;
在这一点上,我们可以写:

i := foo;  // i is an integer, so the function is called
fn := foo; // fn is a procedural type variable, so the function is not called

我个人认为这种情况一点也不令人满意。

起初我认为我不应该这样做,但在看到答案后,我+1回答了这个问题。我想知道文档是否强调了这一点。我记得Delphi 2时代的那个问题——大约1996年year@Arioch“事实确实如此。在我的记录所能看出的时间里,我一直在做。Delphi 5帮助与今天的帮助相同;TGenIntFunc=函数:TIntFunc;tgenginentfunc=…
;现在
i:=gf();{TGenIntFunc};i:=ggf()。。。我猜解析器会对调用哪一个感到困惑-D@Arioch“我不这么认为。只要
i
是过程或方法类型,那么函数调用将只使用
()
。没有进行隐式函数调用。但是如果函数返回函数,它调用的是哪一个函数
i:=gf()
返回函数-该函数是否会被隐式调用?@Arioch取决于赋值运算符左侧变量的类型。我猜Delphi核心开发人员自无参数函数应用程序启动以来一直在诅咒它的“功能”;-)。但是,如果你沿着依赖于上下文而做出决定的道路,为什么不随之而来,同时考虑函数类型本身和它的返回类型?这将立即消除像
v1:=GetHandler,因为v1类型需要接收返回值,而不是函数。
type
  TIntFunc = function: Integer;

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

var
  i: Integer;
  fn: TIntFunc;
i := foo;  // i is an integer, so the function is called
fn := foo; // fn is a procedural type variable, so the function is not called