为什么Kotlin Regex匹配结果序列调用map未执行但forEach正常?
问题原因说明
这是Kotlin Sequence 惰性求值机制的正常表现,并非Regex API的异常或Bug。
Regex.findAll()方法的返回值为Sequence<MatchResult>类型,Sequence是Kotlin专为惰性遍历设计的集合类型,所有操作默认不会立即执行。- Sequence的操作分为两类:
- 中间操作:返回值仍为Sequence的操作,比如
map、filter、sorted等,这类操作只会记录待执行的逻辑,不会触发实际的序列遍历,对应lambda也不会运行。 - 终端操作:返回值为非Sequence的操作,比如
forEach、toList、count、first等,只有调用终端操作时,才会触发序列的实际遍历,按顺序执行之前所有累积的中间操作逻辑。
- 中间操作:返回值仍为Sequence的操作,比如
你给出的示例中,regex.findAll(txt).map { counter++ } 仅完成了中间操作的注册,没有调用终端操作,因此map的lambda完全不会执行,counter自然不会变化。而forEach属于终端操作,每次调用都会触发全量遍历,因此两次forEach调用各为counter增加3,最终得到6的结果。
Kotlin官方Sequence相关文档中明确标注了两类操作的差异,所有返回Sequence的操作默认均为惰性操作,必须搭配终端操作才会实际执行。
如果需要让map逻辑生效,只需要在操作链末尾添加终端操作即可,示例如下:
regex.findAll(txt).map { counter++ }.toList() // 执行后counter会增加3
内容的提问来源于stack exchange,提问作者Marcel
相关产品推荐
相关产品推荐

