Scala编程(第4版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

8.3 一等函数

Scala支持一等函数。不仅可以定义函数并调用它们,还可以用匿名的字面量来编写函数并将它们作为value)进行传递。我们在第2章介绍了函数字面量,并在图2.2(31页)中展示了基本的语法。

函数字面量被编译成类,并在运行时实例化成函数值function value)。[2]因此,函数字面量和函数值的区别在于,函数字面量存在于源码,而函数值以对象形式存在于运行时。这跟类(源码)与对象(运行时)的区别很相似。

以下是一个对某个数加1的函数字面量的简单示例:

=>表示该函数将左侧的内容(任何整数x)转换成右侧的内容(x + 1)。因此,这是一个将任何整数x映射成x + 1的函数。

函数值是对象,所以可以将它们存放在变量中。它们同时也是函数,所以也可以用常规的圆括号来调用它们。以下是对这两种操作的示例:

由于本例中的increasevar,可以稍后将它赋值成其他函数值。

如果你想要在函数字面量中包含多于1条语句,可以将函数体用花括号括起来,每条语句占一行,组成一个代码块(block)。跟方法一样,当函数值被调用时,所有的语句都会被执行,并且该函数的返回值就是对最后一个表达式求值的结果。

现在你已经看到了函数字面量和函数值的细节和用法。很多Scala类库都让你有机会使用它们。例如,所有的集合类都提供了foreach方法。[3]它接收一个函数作为入参,并对它的每个元素调用这个函数。如下是使用该方法打印列表中所有元素的例子:

再举个例子,集合类型还有个filter方法。这个方法从集合中选出那些满足由调用方指定的条件的元素。这个指定的条件由函数表示。例如,(x: Int) => x > 0这个函数可以被用来做过滤。这个函数将所有正整数映射为true,而所有其他整数映射为false。如下是filter的具体用法:

foreachfilter这样的方法会在后面的章节详细介绍。第16章会讲到它们在List类中的使用,第17章会讲到它们在其他集合类型中的用法。