匿名函数(也称为 lambda)是作为参数传递给高阶函数的代码块。 维基百科将 匿名函数 定义为“未绑定到标识符的函数定义”。
例如,给定这样的列表:
val ints = List(1, 2, 3)
您可以通过使用 List
类 map
方法和自定义匿名函数将 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
如果您不熟悉这种语法,将 =>
符号视为转换器会有所帮助,因为表达式使用 =>
符号右侧的算法(在这种情况下,一个将 Int
加倍的表达式)把符号左侧的参数列表(名为 i
的 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)
Contributors to this page:
Contents
- 导言
- Scala 3 特性
- 为什么是 Scala 3 ?
- Scala 的味道
- Hello, World!
- The REPL
- 变量和数据类型
- 控制结构
- 领域建模
- 方法
- 头等函数
- 单例对象
- 集合
- 上下文抽象
- 顶层定义
- 总结
- 类型初探
- 字符串插值
- 控制结构
- 领域建模
- 工具
- OOP 领域建模
- 函数式领域建模
- 方法
- 方法特性
- main 方法
- 总结
- 函数
- 匿名函数
- 函数变量
- Eta 扩展
- 高阶函数
- 自定义 map 函数
- 创建可以返回函数的方法
- 总结
- 打包和导入
- Scala 集合
- 集合类型
- 集合方法
- 总结
- 函数式编程
- 什么是函数式编程?
- 不可变值
- 纯函数
- 函数是值
- 函数式错误处理
- 总结
- 类型和类型系统
- 类型推断
- 泛型
- 相交类型
- 联合类型
- 代数数据类型
- 型变
- 不透明类型
- 结构化类型
- 依赖函数类型
- 其他类型
- 上下文抽象
- 扩展方法
- Given 实例和 Using 语句
- 上下文绑定
- Given 导入
- 实现类型类
- 多元相等性
- 隐式转换
- 总结
- 并发
- Scala 工具
- 使用 sbt 构建和测试 Scala 项目
- worksheet
- 与 Java 交互
- 向 Java 开发者介绍Scala
- Scala for JavaScript Developers
- Scala for Python Developers
- 下一步去哪