跳转到内容

Scala/函数字面量

来自维基教科书,开放的书籍,为开放的世界

通常情况下,函数只定义一次就使用。由于它只定义一次,给它命名就显得有点多余。为了避免重复命名和使用一次性函数,存在一个方法可以完全避免为它们命名。这些被称为匿名函数或函数字面量。一个简单的例子是将一个函数转换为匿名版本

def isEqualToFour(a:Int) = a == 4
(a:Int) => a == 4

上面两个函数实际上是一样的,除了第二个函数没有名字。但是上面的例子并不令人兴奋。所以让我们在更高阶函数中应用它,看看它的实际效果

val list = List(1, 2, 3, 4)

list.exists(isEqualToFour)

list.exists((a:Int) => a == 4)

简短了不少,因为之前我们必须写两次“isEqualToFour”,并使用一个“def”。但它可以更短。由于函数字面量是在一个函数内部使用的,Scala编译器可以推断出参数类型

list.exists(a => a == 4)

好多了。但是“a”基本上是一个一次性名字。在更高阶函数内部使用函数字面量时,你可以直接写一个使用“_”作为参数的表达式,而不是定义参数

list.exists(_ == 4)

这个版本尽可能简洁。使用“_”的规则是:第一次使用“_”指的是第一个参数,第二次使用“_”指的是第二个参数,以此类推。所以下面的例子就不行了,因为函数字面量期望只接受一个参数,但两次使用“_”意味着函数字面量有两个参数

list.exists(a => a*a == 4) //Compiles fine.
//list.exists(_*_ == 4) //ERROR: Does not compile!
华夏公益教科书