0

更新

我正在设计一种实验性编程语言,问题是包括闭包还是只使用一流的函数。为了决定这一点,我需要现实的用例/示例来展示闭包优于一流函数的好处。我知道如果没有它们,您可以使用两者中的一个来实现您可以实现的一切,但是有几个用例例如一流的功能,其中代码更易于阅读(例如更短或不分为几个类)。例如:

红宝石:

[1,5,7].map{|x| x*x }
[1,'test',3].select{|x| x.kind_of? Integer}.map{|x| x.to_s }
big_array.each{ |item| puts item }

如果没有一流的函数,这些示例将更加冗长,因为您将不得不使用 for 循环或类似的东西。

现在,哪些用例显示了闭包的用处?尽管我经常使用一流的函数,但我真的想不出好的闭包用例。你有什么好的闭包用例吗?

原帖

我不明白为什么闭包绑定到变量而不仅仅是,例如:

红宝石:

x = 5
l = lambda { x }
l.call #=> 5
x = 100
l.call #=> 100

引用变量而不是仅仅在定义闭包时引用存储在变量中的值有什么用?就像在这个例子中一样:

红宝石:

x = 5
l = lambda { x }
l.call #=> 5
x = 100
l.call #=> 5, not 100

是否有很好的用例需要在定义闭包时引用变量而不仅仅是这些变量的值?

4

2 回答 2

1

闭包的全部意义在于关闭状态可以改变。可以说,关闭不会(或不能)改变的东西是不好的形式,因为你隐藏了一个参数。

以 C# 中的以下人为示例:

var sb=new StringBuilder();
int counter = 0;
var Append=(int a, string s)=>
            sb.Append(a*a + counter++, SomethingElse(s, "some constant"));

Append关闭 StringBuilder 和计数器,这样我就可以通过我的代码对它进行调用,而不必每次都通过SomethingElseand仪式。sb.Append如果闭包内部的状态不能改变,闭包对这种事情的用处就会降低。

于 2010-10-18T23:49:18.303 回答
0

据我了解(如果我错了,请帮助我)在 lambda 表达式中使用变量将变量(例如“Foo as Widget”)更改为 New Holder(Of Widget),定义如下所示,并更改所有对 Foo 的引用变成对 Foo.Value 的引用。然后将封闭变量的持有者作为参数传递给委托工厂。

班级持有人(T)
  公共价值作为 T

  子新(NewValue As T)
    价值 = 新价值
  结束子
结束类

我不太确定额外的包装层多久真正有用。我认为更常见的是人们想要按值获取局部变量。在我自己的代码中,在升级到支持 lambda 的 VB 版本之前,我使用了委托工厂,例如

  Sub SetText(ByVal St As String)
    文字=圣
  结束子

  ...其他地方
    MyControl.BeginInvoke(NewInv(AddressOf SetText, someExpression ))

请注意,将在执行 BeginInvoke 本身时评估someExpression,而不是在实际执行延迟操作时评估。另请注意,我的 NewInv() 系列函数支持 1-4 个参数的通用覆盖,并且如果需要一个 Action(Of T) 而不是 MethodInvoker,我有一个通用静态类和另一个函数系列。

顺便说一句,这种方法的一个优点是:它适用于编辑/继续。

于 2010-10-30T02:51:32.800 回答