虽然每个已创建的编程语言可能都允许你编写纯函数,但第二个重要的 Scala FP 特性是你可以将函数创建为值,就像你创建 String
和 Int
值一样。
此特性有很多好处,最常见的好处是 (a) 你可以定义方法来接受函数参数,以及 (b) 你可以将函数作为参数传递到方法中。你已在此书中的多个地方看到过这一点,每当演示 map
和 filter
等方法时
val nums = (1 to 10).toList
val doubles = nums.map(_ * 2) // double each value
val lessThanFive = nums.filter(_ < 5) // List(1,2,3,4)
在这些示例中,匿名函数被传递到 map
和 filter
中。
匿名函数也称为lambda。
除了将匿名函数传递到 filter
和 map
中之外,你还可以向它们提供方法
// two methods
def double(i: Int): Int = i * 2
def underFive(i: Int): Boolean = i < 5
// pass those methods into filter and map
val doubles = nums.filter(underFive).map(double)
将方法和函数视为值处理的能力是函数式编程语言提供的强大功能。
从技术上讲,将另一个函数作为输入参数的函数称为高阶函数。(如果你喜欢幽默,就像有人曾经写的那样,这就像说一个将另一个类的实例作为构造函数参数的类是一个高阶类。)
函数、匿名函数和方法
如你在那些示例中看到的那样,这是一个匿名函数
_ * 2
如高阶函数讨论中所示,这是此语法的简写版本
(i: Int) => i * 2
像这样的函数被称为“匿名”,因为它们没有名称。如果你想给一个函数命名,只需将其分配给一个变量
val double = (i: Int) => i * 2
现在你有一个命名函数,它被分配给一个变量。你可以像使用一个方法一样使用这个函数
double(2) // 4
在大多数情况下,double
是函数还是方法并不重要;Scala 允许你以相同的方式对待它们。在幕后,Scala 技术允许你将方法像函数一样对待,称为Eta 扩展。
将函数无缝地作为变量传递的能力是 Scala 等函数式编程语言的一个显著特征。正如你在本书中看到的map
和filter
示例中一样,将函数传递到其他函数中的能力可以帮助你创建简洁且仍然可读的代码——富有表现力。
如果你不习惯将函数作为参数传递到其他函数的过程,这里有一些你可以尝试的更多示例
List("bob", "joe").map(_.toUpperCase) // List(BOB, JOE)
List("bob", "joe").map(_.capitalize) // List(Bob, Joe)
List("plum", "banana").map(_.length) // List(4, 6)
val fruits = List("apple", "pear")
fruits.map(_.toUpperCase) // List(APPLE, PEAR)
fruits.flatMap(_.toUpperCase) // List(A, P, P, L, E, P, E, A, R)
val nums = List(5, 1, 3, 11, 7)
nums.map(_ * 2) // List(10, 2, 6, 22, 14)
nums.filter(_ > 3) // List(5, 11, 7)
nums.takeWhile(_ < 6) // List(5, 1, 3)
nums.sortWith(_ < _) // List(1, 3, 5, 7, 11)
nums.sortWith(_ > _) // List(11, 7, 5, 3, 1)
nums.takeWhile(_ < 6).sortWith(_ < _) // List(1, 3, 5)
此页面的贡献者
内容
- 简介
- Scala 特性
- 为什么选择 Scala 3?
- Scala 尝鲜
- 你好,世界!
- REPL
- 变量和数据类型
- 控制结构
- 领域建模
- 方法
- 一类函数
- 单例对象
- 集合
- 上下文抽象
- 顶级定义
- 摘要
- 初探类型
- 字符串插值
- 控制结构
- 领域建模
- 工具
- OOP 建模
- FP 建模
- 方法
- 方法特性
- Scala 3 中的主要方法
- 摘要
- 函数
- 匿名函数
- 函数变量
- Eta 展开
- 高阶函数
- 编写你自己的 map 方法
- 创建返回函数的方法
- 摘要
- 打包和导入
- Scala 集合
- 集合类型
- 集合方法
- 摘要
- 函数式编程
- 什么是函数式编程?
- 不可变值
- 纯函数
- 函数即值
- 函数式错误处理
- 摘要
- 类型和类型系统
- 推断类型
- 泛型
- 交集类型
- 并集类型
- 代数数据类型
- 变体
- 不透明类型
- 结构类型
- 依赖函数类型
- 其他类型
- 上下文抽象
- 扩展方法
- 上下文参数
- 上下文界限
- Given 导入
- 类型类
- 多重相等
- 隐式转换
- 摘要
- 并发
- Scala 工具
- 使用 sbt 构建和测试 Scala 项目
- 工作表
- 与 Java 交互
- 面向 Java 开发人员的 Scala
- 面向 JavaScript 开发人员的 Scala
- 面向 Python 开发人员的 Scala
- 下一步