为什么我不能在 Kotlins 正则表达式结果序列上使用地图
Why can't I use map on Kotlins Regex Result sequence
我使用 Kotlin 的正则表达式 API 来获取一些正则表达式的出现。我想将发现直接转换为另一个对象,所以我凭直觉在结果序列上使用了 map()
。
map
函数 从未被调用 但 forEach
正在运行,这让我感到非常惊讶。这个例子应该说清楚了:
val regex = "a.".toRegex()
val txt = "abacad"
var counter = 0
regex.findAll(txt).forEach { counter++ }
println(counter) // 3
regex.findAll(txt).map { counter++ }
println(counter) // still 3 since map is not called
regex.findAll(txt).forEach { counter++ }
println(counter) // 6
我的问题是为什么?我在文档中监督了吗?
(在 Kotlin 1.5.30 上测试)
findAll()
returns一个Sequence<MatchResult>
。 Sequence 上的操作被分类为 intermediate 或 terminal。函数的文档声明了它们的类型。 map
和 onEach
是中间的。他们的行动被推迟,直到进行终端操作。 forEach
是终端。
用 map
操作一个序列 returns 一个新的序列,它只会在实际迭代时执行映射函数,例如通过调用 forEach
或在中使用它一个 for 循环。
这就是 Sequence 的目的,即推迟变异函数调用。它可以减少中间列表的分配,或者在某些情况下避免对每个项目应用突变,例如如果链中的终端调用是 find()
调用。
我使用 Kotlin 的正则表达式 API 来获取一些正则表达式的出现。我想将发现直接转换为另一个对象,所以我凭直觉在结果序列上使用了 map()
。
map
函数 从未被调用 但 forEach
正在运行,这让我感到非常惊讶。这个例子应该说清楚了:
val regex = "a.".toRegex()
val txt = "abacad"
var counter = 0
regex.findAll(txt).forEach { counter++ }
println(counter) // 3
regex.findAll(txt).map { counter++ }
println(counter) // still 3 since map is not called
regex.findAll(txt).forEach { counter++ }
println(counter) // 6
我的问题是为什么?我在文档中监督了吗?
(在 Kotlin 1.5.30 上测试)
findAll()
returns一个Sequence<MatchResult>
。 Sequence 上的操作被分类为 intermediate 或 terminal。函数的文档声明了它们的类型。 map
和 onEach
是中间的。他们的行动被推迟,直到进行终端操作。 forEach
是终端。
用 map
操作一个序列 returns 一个新的序列,它只会在实际迭代时执行映射函数,例如通过调用 forEach
或在中使用它一个 for 循环。
这就是 Sequence 的目的,即推迟变异函数调用。它可以减少中间列表的分配,或者在某些情况下避免对每个项目应用突变,例如如果链中的终端调用是 find()
调用。