当今世界主流编程语言无不吸纳强大的闭包概念,但有个例外,它就是Java。数年来,Java语言中增加闭包特征的工作看起来毫无进展。

上一篇C++的博客是Long Long
ago了,前文讲到在看Lambda表达式的内容。笔者首次接触Lambda表达式应该是学习Python语言的时候,当时也不太明白这种表达方式的精髓,后续接触了Scala与Java8的链式调用与Lambda结合的方式,深陷无法自拔。所以借上一篇闭包的内容。我们来完整的梳理一下C++之中的Lambda表达式。

早在15年之前,Scala语言和TypeSafe框架的作者Martin Odersky和Phillip
Wadler发布了实验性的“Pizza”项目,由此,人们开始试图将闭包纳入编程语言的基本特征之一。尽管这看起来有点过于复杂,Java社区大概在2008年就有了接纳闭包概念的想法。但由于Oracle对Sun微系统公司的匆忙收购,Java被冷落,Java语言新版本的发布不断的被推迟。

Lambda表达式是函数式编程的重要的语法结构。Lambda 表达式(lambda
expression)说起来很简单,就是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包。(注意和数学传统意义上的不同)。(本质上Lambda表达式就是将函数作为是一个匿名对象进行操作

但在Java8中,事情有了很大的变化,Java语言终于为Java编程部队配备了闭包的武器。“也许这是Java编程语言有史以来最重要的一次升
级,”Oracle的Java语言架构师Brian
Goetz说。他指出,在Java中引入闭包概念对Java程序开发方法的影响甚至会大于Java5中引入的泛型特征对编程方式带来的影响。“就像泛型能使开发人员对数据类型进行抽象,Lambda的目的是让程序员能够对程序行为进行抽象。”

其实缺少Lambda表达式的编程语言并不会影响编程语言的逻辑表达,Lambda表达式核心就是提供一个好用的语法糖:可以直接定义一个函数,而不需要将定义函数和语法内容分开,这样有助于将逻辑用更紧凑的方式表达出来。假如需要定义一个函数,恰巧这个函数仅仅使用一次,然后又需要给它定义一个名字,作为懒惰的程序员就需要搬出Lambda表达式了。咱们看一段Python代码,过滤一个list之中的偶数,这是一个很简单的需求,我们先看看不使用Lambda表达式的方式:

Lambda这个名称来自于把闭包绑定到Java编程语言的Lambda项目。Lambda以及闭包的引入能做些什么?你可以这样想,它能够让程序
员把一段程序代码当做数据一样使用。一个方法可以像定义和使用一个变量那样的方式被定义和使用,定义出的方法可以被当作参数传递到其它方法内,就像它们是
一个对象实例或一个类型数据一样。“看起来这好像也没什么,但实际上它影响巨大,”Goetz说。“这将从根本上改变我们开发java程序的方式。”

def isOdd: return n & 1;nums = [1,2,3,4,5,6]nums = filter(isOdd,nums)

我们等待了太久,但随着Java8的发布,Lambda终于成为Java规格说明书里的正式特征之一。一种由于过于复杂而最初被传统程序员放弃的语法将最终成为一种每个现代Java应用程序里都能看到的标准技术。

显然这里需要额外定义一个代码逻辑十分麻烦:首先需要跳脱出运行代码而去查看定义的isOdd函数的代码,其次,这里需要实现的过滤逻辑很简单。这种场合是最适合使用Lambda表达式的场景,我们来看看Lambda表达式是怎么优化上述代码的:

[本文英文原文链接:Lambda in Java 8: A fundamental change in how Java
programs are
developed
]

nums = [1,2,3,4,5,6]nums = filter(lambda x:x & 1,nums)

本文转载自: 外刊IT评论

好吧,很优雅的用Lambda表达式解决了同样的需求,表述也十分清晰:下面的几个使用场景是适用于Lambda表达式的:

  • 代码定义的逻辑与执行逻辑对接的更加紧凑。
  • 代码更加简洁。
  • 能够支持闭包。

C++在C++11之中添加了Lambda表达式的语法结构,Lambda语法结构如下所示:

[capture](parameters)->return-type {body}

接下来,我们来一一分析各个部分所代表的含义,以及具体的使用方式:

  • [capture]capture代表捕获外部的变量,这个使用的方式笔者在上一篇有关闭包的内容之中就有过示例,变量捕获是Lambda表达式之中,最为复杂的一环,我们来看一看其中各种表示方式的含义:
    • []
      不捕获任何变量(但是必须得写,编译器通过捕获结构识别Lambda表达式澳门新葡亰8455下载app,)
    • [&} 通过引用的方式捕获外部作用域中所有变量
    • [=]
      通过拷贝的方式捕获外部作用域中所有变量(上述两种方式都过于粗暴了,实际的话,尽量采用下面的模式来限定所引用的变量,不要随意引用
    • [x, &y] x按值传递,y按引用传递
    • [this]
      截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。
网站地图xml地图