为何Match对象在for循环的尖块中输出Nil而非预期值?
为什么Raku的Match对象在for循环中输出Nil,而given中正常?
我们先看测试的Match对象:它是有效的、已定义的,能获取到匹配的文本长度:
say Match.new(:orig("20230213112803"), :from(4), :pos(6)).elems; # 0 say Match.new(:orig("20230213112803"), :from(4), :pos(6)).chars; # 2 say Match.new(:orig("20230213112803"), :from(4), :pos(6)).defined; # True
但用for循环迭代这个Match对象时,输出的是Nil:
for Match.new(:orig("20230213112803"), :from(4), :pos(6)) -> $m { say ~$m } # OUTPUT: Nil
而given语句能正常输出匹配的文本02:
given Match.new(:orig("20230213112803"), :from(4), :pos(6)) -> $m { say ~$m } # OUTPUT: 02
核心原因:for和given对Match对象的处理逻辑不同
given是直接将整个对象绑定到变量,所以你操作的是完整的Match实例,能通过~$m获取到它匹配的文本内容。for的行为是迭代对象的可迭代元素,而Match对象的迭代逻辑是遍历它的捕获组(子匹配),不是遍历自身。你创建的这个Match对象没有任何捕获组(.elems返回0),所以for没有元素可以迭代,最终输出Nil——这和空数组[]、空哈希{}在for中的表现一致:
for "a" -> $m { say $m } # a(字符串是可迭代的,遍历每个字符) for [] -> $m { say $m } # Nil(空数组无元素) for {} -> $m { say $m } # Nil(空哈希无元素)
如果想让for循环处理这个Match对象本身,可以把它包装成单元素列表:
for (Match.new(:orig("20230213112803"), :from(4), :pos(6))) -> $m { say ~$m } # OUTPUT: 02
内容的提问来源于stack exchange,提问作者ohmycloudy
相关产品推荐
相关产品推荐

