Scala 3 — 书籍

匿名函数

语言

匿名函数(也称为“lambda”)是一段代码块,作为参数传递给高阶函数。维基百科将 匿名函数 定义为“未绑定到标识符的函数定义”。

例如,给定如下列表

val ints = List(1, 2, 3)

你可以使用 Listmap 方法和自定义匿名函数,通过将 ints 中的每个元素加倍来创建新列表

val doubledInts = ints.map(_ * 2)   // List(2, 4, 6)

正如注释所示,doubledInts 包含列表 List(2, 4, 6)。在该示例中,代码的这一部分是一个匿名函数

_ * 2

这是表示“将给定元素乘以 2”的一种简写方式。

较长的形式

一旦你适应了 Scala,你将始终使用该形式来编写在函数中的某个位置使用一个变量的匿名函数。但是,如果你愿意,你也可以使用较长的形式来编写它们,因此除了编写此代码外

val doubledInts = ints.map(_ * 2)

你还可以使用这些形式来编写它

val doubledInts = ints.map((i: Int) => i * 2)
val doubledInts = ints.map((i) => i * 2)
val doubledInts = ints.map(i => i * 2)

所有这些行的含义完全相同:将 ints 中的每个元素加倍以创建一个新列表 doubledInts。(每种形式的语法将在稍后进行说明。)

如果你熟悉 Java,那么了解这些 map 示例等效于以下 Java 代码可能会有所帮助

List<Integer> ints = List.of(1, 2, 3);
List<Integer> doubledInts = ints.stream()
                                .map(i -> i * 2)
                                .collect(Collectors.toList());

缩短匿名函数

当你想要明确时,可以使用此长格式编写匿名函数

val doubledInts = ints.map((i: Int) => i * 2)

该表达式中的匿名函数如下

(i: Int) => i * 2

如果你不熟悉此语法,那么将 => 符号视为转换器会有所帮助,因为表达式转换符号左侧的参数列表(一个名为 iInt 变量)成一个新的结果,使用 => 符号右侧的算法(在本例中,一个将 Int 加倍的表达式)。

缩短该表达式

此长格式可以缩短,如下面的步骤所示。首先,再次给出最长和最明确的形式

val doubledInts = ints.map((i: Int) => i * 2)

由于 Scala 编译器可以从 ints 中的数据推断出 i 是一个 Int,因此可以移除 Int 声明

val doubledInts = ints.map((i) => i * 2)

由于只有一个参数,因此不需要参数 i 周围的括号

val doubledInts = ints.map(i => i * 2)

由于 Scala 允许你在参数仅在函数中出现一次时使用 _ 符号代替变量名,因此可以进一步简化代码

val doubledInts = ints.map(_ * 2)

进一步缩短

在其他示例中,你可以进一步简化你的匿名函数。例如,从最显式形式开始,你可以使用匿名函数和 List 类的 foreach 方法来打印 ints 中的每个元素

ints.foreach((i: Int) => println(i))

与之前一样,Int 声明不是必需的,并且由于只有一个参数,因此不需要 i 周围的括号

ints.foreach(i => println(i))

因为 i 仅在函数体中使用一次,所以可以使用 _ 符号进一步简化表达式

ints.foreach(println(_))

最后,如果匿名函数包含一个采用单个参数的方法调用,则不需要显式命名和指定参数,因此你最终可以仅编写方法的名称(此处为 println

ints.foreach(println)

此页面的贡献者