delphi D11编程语言手册 匿名方法(P479-495)
这本书可以在 Delphi研习社②群 256456744 的群文件里找到. 书名: Delphi 11 Alexandria Edition.pdf
匿名方法可以让我们把一个方法的实际代码当成参数来进行传递,而不用事先定义,然后把方法的名字当成了参数,另外匿名方法对局部变量的生命周期管理与其他方法的管理也不同.
D中的匿名方法,实际上就是其它语言(如JS)中的闭包!
reference to是定义匿名方法的关键字,我们不必在type阶段就具现方法代码,而上在需要调用的地方再去具现.所以这个匿名方法你可以自由发挥,写出多少个不同版本都是你说了算.用法上面感觉这就应该是inline该干的活.
匿名方法是可以被存储到变量上面的.
type TPR = reference to procedure(var N: Integer); //匿名方法 TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private FAnonMeth: TPR; procedure SetAnonMeth(const Value: TPR); { Private declarations } public { Public declarations } property AnonMeth: TPR read FAnonMeth write SetAnonMeth; //把匿名方法委托到窗体属性 AnonMeth end; var Form1: TForm1; j: Integer; implementation {$R *.dfm} //这个点击事件只是把匿名方法具现,然后存到AnonMeth里 procedure TForm1.Button1Click(Sender: TObject); begin j := 5; AnonMeth := procedure(var N: Integer) begin j := j + N; //匿名方法可以使用外层的局部变量 end; Memo1.Lines.add('Button1Click: ' + j.ToString) end; procedure TForm1.Button2Click(Sender: TObject); var K: Integer; begin K := 10; if Assigned(AnonMeth) then //检查AnonMeth是否为nil begin AnonMeth(K); //调用里面的方法 Memo1.Lines.add('Button2Click: ' + j.ToString) end; end; procedure TForm1.SetAnonMeth(const Value: TPR); begin FAnonMeth := Value; end;
假如有这样一个匿名方法,第三参数PR也是一个匿名方法,则PR是可以在内部使用X,Y这两个参数的.
type TTest:= reference to function(x,y:integer;PR:TPR):integer;
使局部变量,提升为全局变量
type // 首先声明匿名方法的类型 TIntSum = reference to procedure(x, y: Integer); type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; 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; memo1.Lines .add(format('x + y = %d', [lResult])); end; end;
FormCreate中把匿名函数的功能给实现了,lResult初始值为100.
按理说FormCreate结束后lResult作为局部变量也就无法再访问,但是由于匿名函数内部使用了lResult,lResult := lResult + x + y;
之后其他地方调用匿名函数会不断的重复使用lResult,而且每次用完lResult的值是会保存下来供下次使用的.就像全局变量一般.