Delphi 新语法:匿名函数

这里的新语法一般指Delphi7不支持的语法.
对于比较简单实现,不需要复用,开发者更喜欢在使用时,原地声明,而没有必要单独声明并实现这个方法.

通过关键字reference来定义一个匿名函数.

下面直接来段简单的代码

type
  // 首先声明匿名方法的类型(两个整形参数,返回值亦是整形)
  TIntSum = reference to function(x, y: Integer): Integer;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    function Calc(x, y: Integer; intSum: TIntSum): Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessageFmt('x + y = %d', [Calc(10, 15,
    function(x, y: Integer): Integer
    begin
      Result := x + y;
    end)]);
end;

function TForm1.Calc(x, y: Integer; intSum: TIntSum): Integer;
begin
  Result := intSum(x, y);
end;

对代码进行简化在简化是为了我们方便理解.

  1. type
    // 首先声明匿名方法的类型
    TIntSum = reference to function(x, y: Integer): Integer;

  2. function Calc(x, y: Integer; intSum: TIntSum): Integer;
    begin
    Result := intSum(x, y);
    end;

  3. Calc(10, 15,
    function(x, y: Integer): Integer
    begin
    Result := x + y;
    end);

2中的Calc函数第三个参数是匿名函数,一会你们谁想用这个函数,得先把第三个参数(匿名函数)具体用法给我实现了在传进来.
3中开始调用Calc,果然直接就开始实现函数具体的功能:
function(x, y: Integer): Integer//不要带什么符号
begin
Result := x + y;
end
这函数啥功能?两个参数相加,然后返回.好了,最后看下
function Calc(x, y: Integer; intSum: TIntSum): Integer;
begin
Result := intSum(x, y);
end;
第三个参数被传进来的同时,这个函数的功能也已经被传进来,而且这个匿名函数intSum还可以调用前面的参数x和y.

好像有点搞,不使用这种语法也可以编程,但我们不使用不等于别人不使用,学会了方便阅读别人的源代码.

使用本地变量

匿名函数功能实现部分是可以使用外一层的变量的.
看如下代码:

type
  // 首先声明匿名方法的类型
  TIntSum = reference to procedure(x, y: Integer);

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    function Calc(x, y: Integer; intSum: TIntSum): Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  lResult: Integer;
begin
  Calc(40, 30,
    procedure(x, y: Integer)
    begin
      lResult := lResult + x + y;
    end);
  ShowMessageFmt('x + y = %d', [lResult]); // 调用三次,结果是210
end;

function TForm1.Calc(x, y: Integer; intSum: TIntSum): Integer;
begin
  intSum(x, y);
  intSum(x, y);
  intSum(x, y);
end;

lResult 是外一层的变量,匿名函数内部可以使用.

扩展本地变量的生命周期

本地变量,一般是随着函数执行结束,就不能再访问;
而如果在匿名函数,访问了外部函数的本地变量,本地变量的生命周期会被扩展
看如下代码:

type
  // 首先声明匿名方法的类型
  TIntSum = reference to procedure(x, y: Integer);

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    function Calc(x, y: Integer; intSum: TIntSum): Integer;

  public
    intSum: TIntSum;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Calc(40, 30, intSum);
end;

function TForm1.Calc(x, y: Integer; intSum: TIntSum): Integer;
begin
  intSum(x, y);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  lResult: Integer;
begin
  lResult := 100;
  intSum := procedure(x, y: Integer)
            begin
              lResult := lResult + x + y;
              ShowMessageFmt('x + y = %d', [lResult]);
            end;
end;

现在FormCreate中把匿名函数的功能给实现了,lResult初始值为100.
按理说FormCreate结束后lResult作为局部变量也就无法再访问,但是由于匿名函数内部使用了lResult,lResult := lResult + x + y;
之后其他地方调用匿名函数会不断的重复使用lResult,而且每次用完lResult的值是会保存下来供下次使用的.就像全局变量一般.

参考:https://www.cnblogs.com/iihe602/archive/2013/02/21/2920694.html

posted on   YXGust  阅读(654)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)

导航

点击右上角即可分享
微信分享提示