lambda and closure

lambda又称为lambda表达式lambda演算子,名字听起来挺高端,其实在编程语言里倒也不难理解。但是,和lamba相比闭包却没那么直观。这两个概念作为函数式编程基础的一部分,是必须要掌握的。另外,Java 8也引入了lambda表达式,C#也从版本3.0后开始支持lambda,可见这些函数式编程的特性已经逐渐被主流的面向对象语言所借鉴吸收。

下面的正文部分译自Scala in action的一段解释,算是对这两个概念的初步澄清。在译文后面的参考链接中,我也列举了一些资源,从而帮助理解lambda和闭包的概念以及在不同语言中的应用。

lambda算子

lambda和闭包(closure)的区别是什么

lambda就是匿名函数——即没有名字的函数。前面你已经看到过一些例子了。闭包就是封闭在其定义所处环境的任意函数。让我们用一个例子来解释一下,比如,将一个百分比应用到一个列表上:

1
2
scala> List(100, 200, 300) map { _ * 10/100 }
res34: List[Int] = List(10, 20, 30)

在这个例子中,传递给map的函数就是一个lambda表达式(译者注:其中 _ * 10/100也可以写成(x:Int) => x * 10/100)或x => x * 10/100)。现在假设这个百分比数值会随着时间变化,所以要把当前的百分比数值存在一个变量里。

1
2
3
4
5
scala> var percentage = 10
percentage: Int = 10
scala> val applyPercentage = (amount: Int) =>
amount * percentage/100
applyPercentage: (Int) => Int = <function1>

在这种情况下,applyPercentage就是一个闭包,因为它保持了它被创建时的环境,此处主要是percentage变量:

1
2
3
4
scala> percentage = 20
percentage: Int = 20
scala> List(100, 200, 300) map applyPercentage
res33: List[Int] = List(20, 40, 60)

lambda和闭包是不同的概念,但却紧密相关。

参考资源

  1. 中文维基百科:λ演算的定义
  2. 中文维基百科:匿名函数的定义及其在编程语言中的应用情况
  3. 中文维基百科:闭包的定义
  4. 酷壳:理解Javascript的闭包
  5. 阮一峰的网络日志:学习Javascript的闭包
  6. 知乎:Lambda表达式有何用处?如何使用?
  7. 徐青枫的技术博客:说说Java8中的Lambda表达式
  8. Stackoverflow:Closure in Java 7
  9. Oracle文档库:Java 8的lambda表达式指南
  10. MSDN:C#中的lambda表达式编程指南
  11. Stackoverflow:C++ 11中的lambda表达式讨论