另一方面,我已经阅读了Can someone explain Anonymous methods to me?以及与此相关的其他链接,我考虑到可能我错了,所以我要求你给我一些例子,最好是使用闭包而不是’老式’方法(不使用闭包).
解决方法
我可以想到至少十个匿名方法真正有意义的地方,因此,你应该使用它们的原因,尽管我之前的评论是我不信任它们.我只会指出我决定亲自使用的两个,以及我使用它时对自己的限制:
> Generics.Collections中容器类中的排序方法接受匿名方法,这样您就可以轻松地提供逻辑排序位,而无需编写与排序方法所期望的相同签名匹配的常规(非匿名)函数.新的泛型语法与这种风格紧密相关,虽然它起初看起来很陌生,但它会逐渐增长,如果不是非常好用,至少比替代方案更方便.
>像Synchronize这样的TThread方法是重载的,除了支持单个TThreadMethod作为参数Thread.Synchronize(aClassMethodWithoutParameters)之外,对于我来说,将参数引入同步方法一直是一个痛苦的根源.现在你可以使用一个闭包(匿名方法),并传入参数.
我在编写匿名方法时建议的限制:
答:我有一个个人经验法则,每个函数只有一个闭包,每当有多个闭包时,将该位代码重构为自己的方法.这可以使你的“方法”的圈复杂性变得疯狂.
B.此外,在每个闭包内部,我更喜欢只有一个方法调用及其参数,如果我最终编写巨大的代码块,我会将它们重写为方法.闭包是为了变量捕获,而不是用于编写无休止扭曲的意大利面条代码的全权委托.
样品分类:
var aContainer:TList<TPair<String,Integer>>; begin aContainer.Sort( TMyComparer.Construct( function (const L,R: TPair<String,Integer>): integer begin result := SysUtils.CompareStr(L.Key,R.Key); end ) {Construct end} ); {aContainer.Sort end} end;
更新:一条评论指向“语言uglification”,我相信uglification指的是必须写的区别:
x.Sort( TMyComparer.Construct( function (const L,R.Key); end ) );
而不是,我刚刚在这里发明的用于比较的以下假设的鸭型(或者我应该说的推断类型)语法:
x.Sort( lambda( [L,R],[ SysUtils.CompareStr(L.Key,R.Key) ] ) )
其他一些语言如Smalltalk和Python可以更简洁地编写lambda,因为它们是动态类型的.例如,对IComparer的需求,作为传递给容器中的Sort()方法的类型,是由接口风格引起的复杂性的一个例子,为了实现诸如排序之类的特性,必须遵循强类型语言的泛型,可分拣性要求.我不认为有一个很好的方法来做到这一点.就个人而言,我讨厌在函数调用括号内查看过程,开始和结束关键字,但我看不出还有什么可以合理地完成.