众所周知,scala作为一门极客型的函数式编程语言,支持的特性包括:
函数拥有“一等公民”身份;
支持匿名函数(函数字面量)
支持高阶函数
支持闭包
部分应用函数
柯里化
首先需要指出,在scala中有方法和函数对象两种形态,方法即是通过def关键字定义的函数,而函数对象则是通过将方法转换而来,或lambda赋值而来。
1. 从“一等公民”说起
很多稍微了解过函数式编程的人可能都听说过“一等公民”这种说法,但却很少有人能明明白白地说出究竟什么是“一等公民”。这里我做个类比你马上就明白了:现实中,什么样的人能被当做一等公民?首先,他必须是个独立的个体——依赖父母或朋友才能生存的人肯定不能被当做公民,更不用说一等了;其次,这个人必须拥有足够的自由——既能上九天揽月,又可下五洋捉鳖,方才能是一等公民。对应到我们的函数式编程,我们可以总结出几个点:
(1) 函数的定义和调用不依赖其他结构,例如C、python、js、scala,而反面典型就是java,因为java的任何函数(方法)都必须定义在类、接口、枚举(其实也是类)中,而且任何的方法调用都要通过对象、类的静态方法或接口(jdk 1.8),方法不可能直接调用,必须依附于其他结构而存在。所以这种情况下函数肯定不是“一等公民”。
(2)函数可以作为函数的参数、返回值,并可以对函数进行变量赋值,而且函数的定义位置极度自由,任何代码块里又能定义函数。
现在我们再来看scala,它完美地契合上边所有的需求(但是注意,除了脚本形式的scala之外,其他的scala程序也只能包含在class或object中),scala中函数支持在函数内部定义,而且使用lambda表达式定义的函数可以赋值给任何变量、常量,所有函数均可作为返回值、参数。
2. lambda表达式的学问
很多scala初学者都倒在了scala的lambda上,因为scala lambda的灵活多样,导致很多时候你可能都看不懂。下面我们从最基本的讲起:
最基本的:
val fun = (a:Int) => {a < 100 && a > 0}