java8函数式编程闭包_java8入门必备—函数式编程思维——函数式语言向语言和运行时让渡控制权的途径——迭代让位于高阶函数、闭包...

构造一层又一层的抽象来处理(并隐藏)琐碎的细节。随着硬件能力的提高,将越来越多的任务转嫁给语言和运行时。

函数式思维的好处之一,是能够将低层次细节(如垃圾收集)的控制权移交给运行时,从而消弭了一大批注定会发生的程序错误。

不管层次高低,抽象的目的总是一样的:让开发者从繁琐的运作细节里解脱出来,去解答问题中非重复性的那些方面。

函数式语言向语言和运行时让渡控制权,让开发者抛开负累,投入到更有意义的问题中去。

函数式语言向语言和运行时让渡控制权的途径——迭代让位于高阶函数

用map等函数替换了迭代。如果能够用高阶函数把希望执行的操作表达出来,语言将会把操作安排得更高效,甚至只要增加一行par修饰,就能够让操作并行化。

多线程代码属于最难编写,最容易出错,也最难调试的类别。只有卸下线程管理这份头痛的差事,开发者才能少一些低层次的琐碎操劳。

理解掌握的抽象层次永远要比日常使用的抽象层次更深一层

程序员的工作效率依赖于抽象层。抽象隐藏了繁杂的细节,只是有时候会连同重要的考虑因素一起隐藏掉。

开发者不应该抛开所有的责任,不去理解低层次抽象的来龙去脉。使用抽象必须清楚可能产生的连带后果,理解底层的抽象细节才能写出高性能的代码。

当你掌握了背后的原理,才能把力量用在最正确的地方。

函数式语言向语言和运行时让渡控制权的途径——闭包

闭包(closure)是所有函数式语言都具备的一项平常特性。

闭包,实际上是一种特殊的函数,它在暗地里绑定了函数内部引用的所有变量。这种函数(或方法)把它引用的所有东西都放在一个上下文里“包”了起来。

函数式语言向语言和运行时让渡控制权的途径——闭包——Groovy代码演示闭包的创建和绑定

4d71af69e76a

带有amount参数的paidMore函数,其返回值是一个以Employee实例为参数的代码块,或者叫闭包。类型声明Employee可写可不写,这里写出来顺便起到文档的作用。

给代码块传入参数值100 000,并赋予isHighPaid的名称,于是数值100 000就随着这一步赋值操作,永久地和代码块绑定在一起了。以后有员工数据被代入这个代码块求解的时候,它就可以拿绑定的数值作为标准去评判员工的工资高低。

执行闭包:

4d71af69e76a

闭包在生成的时候,会把引用的变量全部圈到代码块的作用域里,封闭、包围起来(故名闭包)。

闭包的每个实例都保有自己的一份变量取值,包括私有变量也是如此。可以创建paidMore闭包的另一个实例,给它绑定另外的数值(当然实例的名字也要另取)

绑定另一个闭包:

4d71af69e76a

闭包经常被函数式语言和框架当作一种异地执行的机制,用来传递待执行的变换代码,如map()之类的高阶函数。在缺乏闭包特性的旧版Java平台上,Functional Java利用匿名内部类来模仿“真正的”闭包的某些行为,但语言的先天不足导致这种模仿是不彻底的。

函数式语言向语言和运行时让渡控制权的途径——闭包——原理

4d71af69e76a

makeCounter()函数首先定义一个局部变量(local_variable),接着返回一个使用了该局部变量的代码块。

注意makeCounter()函数的返回类型是Closure,而不是一个单纯的值。代码块的工作仅仅是递增并返回其局部变量的值。方法中两次明确写出了return关键字,其实这两个地方Groovy都允许省略。

调用代码块的时候用到了Groovy提供的语法糖衣,即在代码块变量名后直接跟一对圆括号的写法(否则应该写成c1.call())。

虽然局部变量不是在代码块里面定义的,但只要代码块引用了该变量,两者就被绑定在一起,这种联系在代码块实例的全部生命期内都一直保持着。

从实现的角度来说,代码块实例从它被创建的一刻起,就持有其作用域内一切事物的封闭副本。当代码块实例被垃圾收集的时候,它持有的引用也同时被回收。

创建一个闭包仅仅为了修改自身的内部状态,不是值得提倡的闭包用法,更常见的用法是绑定常量或者不可变的值。

函数式语言向语言和运行时让渡控制权的途径——闭包——Java8之前的模拟

4d71af69e76a

Counter类还可以有别的一些写法(比如写成匿名的、泛型的,等等),但不管怎么做,都避免不了要自己去管理状态。闭包在这里表现出来的函数式思维就是“让运行时去管理状态”。比起自己硬着头皮去处理字段创建、呵护状态(包括经受多线程环境的严酷考验)这些繁琐的事务,还不如交出对状态的控制权,让语言和框架悄悄在背后帮我们管理好。

函数式语言向语言和运行时让渡控制权的途径——闭包——抓住上下文,而非状态

让语言去管理状态。

闭包还是推迟执行原则的绝佳样板。把代码绑定到闭包之后,可以推迟到适当的时机再执行闭包。这个特点在很多场合都能发挥作用。例如必要的变量和函数可能并不在定义时的作用域里,要到执行的时候才准备好。那么把执行上下文放在闭包里保留起来,就可以等到正确的时机再完成执行。

命令式语言围绕状态来建立编程模型,参数传递是其典型特征。闭包作为一种对行为的建模手段,让把代码和上下文同时封装在单一结构,也就是闭包本身里面,像传统数据结构一样可以传递到其他位置,然后在恰当的时间和地点完成执行。

抓住上下文,而非状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值