函数定义是编程语言的基本能力。一等公民 Java作为一个用类来实现面向对象编程的语言,类是作为一等公民存在的。类可以被自由的定义在几乎任何地方:类里、方法里,类可以被自由的赋值给一个值,自由的被作为函数参数传来传去。 而函数的地位明显是低人一等的。哪怕再简单的函数,比如无参、返回值为void的run方法,都需要引入一个Runnable接口,才能把它赋值给某个变量。 可以这么说,在Java的世界里,函数是类的附庸。我们知道,函数是逻辑的表达,如果每一个函数都需要一个对应的类作为载体,对于程序员和机器的负担未免都太重了。 而在函数式编程的世界里,不用如此繁琐,函数就是一等公民。也就是说:函数可以被自由的定义在任何地方,包括类里、函数里。函数可以被自由的赋值给一个值,我们称之为functionvalue。函数可以被自由的作为参数传来传入。 Scala作为同时支持两种范式,并且更倾向于函数式的编程语言,自然是把函数作为了一等公民。函数值和函数字面量 函数值(functionvalue)是说,可以把函数字面量(functionliterals)赋值给一个值。 比如:valadd1(x:Int)x1 这个时候,如果直接调用add1(10)会得到11这个结果。而其中的(x:Int)x1,就是我们所说的函数字面量。 Java从8开始引入了Lambda表达式,绝大多数时候,我都是把函数字面量直接等价于Lambda表达式的。 但是在读《ProgramminginScala》的时候,作者说: Thusthedistinctionbetweenfunctionliteralsandvaluesisthatfunctionliteralsexistinthesourcecode,whereasfunctionvaluesexistasobjectsatruntime。 这种关系用面向对象的观点来类比一下,class是存在于源代码里的,而实例则是存在于运行时的。同样的,函数字面量相当于是模板,函数值相当于运行时的实例。 从刚才那个add1的例子里,这个例子不太好理解,实际上我觉得作者是针对于闭包这个概念提出的这个说法。闭包简介 我们把刚才的add1稍微泛化一下,假设叫sum吧。valsum(x:Int)xmore 等式的右边是一个函数字面量,当然直接敲这句话是不行的,会提示notfound:valuemore,也就是找不到more这个玩意,因此我们需要先定义more,比如varmore1,这个时候可以重新定义一下刚才的add1。varmore1valadd1(x:Int)xmore 这和最开始add1的写法是一样的。 如果我们再修改一下more的值为10呢?那么可以很方便的定义出一个add10来。valadd10(x:Int)xmore 其中的函数字面量还是一样的。而根据more的不同,我们有了add1和add10两个函数值。 因此我们说,函数值是函数字面量的运行时表达,两者是实例和模板的关系。