为何嵌套Map在sink上下文无输出,单层Map却正常执行?
为什么两个处于sink上下文的map表现不同?
这背后的核心区别在于惰性序列的消耗时机,以及sink上下文对不同类型Iterable的处理方式:
第一个代码:嵌套map无输出的原因
看这段代码:
<foo bar ber>.map: { $^a.comb.map: { $^b.say}};
外层的map会为每个字符串生成一个内层map的惰性序列对象——注意,此时内层的map并没有真正执行,只是生成了一个待求值的Iterable。当整个外层map的结果处于sink上下文时,Raku的sink处理逻辑会跳过对这些未被消耗的Iterable的求值:因为它们只是“待执行的序列”,没有被强制要求计算元素,所以内层的$^b.say永远不会被触发,自然没有输出。
第二个代码:单个map能输出的原因
再看这段能正常运行的代码:
<foo bar ber>.map: *.say; # OUTPUT: «foobarber»
这里的map生成的是一个由say的返回值(Nil)组成的惰性序列。当这个序列处于sink上下文时,Raku会遍历整个序列来处理每个元素(即使元素是Nil)。而要得到每个Nil,就必须执行对应的*.say操作——这就触发了say的副作用(打印输出),所以你能看到每个字符串被打印出来。
简单总结:
- 嵌套map的外层返回的是“未执行的序列对象”,sink不会去触发它们的执行;
- 单个map返回的是“需要执行才能得到Nil的序列”,sink为了遍历序列,会强制触发每个元素的计算,从而执行了
say。
内容的提问来源于stack exchange,提问作者jjmerelo
相关产品推荐
相关产品推荐

