为什么 for 循环中带有 Match 的尖头块输出 Nil?

ohm*_*udy 8 regex raku

在我看来,有效的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
Run Code Online (Sandbox Code Playgroud)

但以下带有循环输出Match中的对象的尖头块:forNil

for Match.new(:orig("20230213112803"), :from(4), :pos(6)) -> $m {
    say ~$m
}
# OUTPUT: Nil
Run Code Online (Sandbox Code Playgroud)

但该given声明输出了我所期望的:

given Match.new(:orig("20230213112803"), :from(4), :pos(6)) -> $m {
    say ~$m
}
# OUTPUT: 02
Run Code Online (Sandbox Code Playgroud)

是不是有一些空的或未定义的东西阻止了for循环的执行?

for "a" -> $m { say $m } # a
for []  -> $m { say $m } # Nil
for {}  -> $m { say $m } # Nil
Run Code Online (Sandbox Code Playgroud)

rai*_*iph 9

TL;DR 始终given将其参数视为件事(对象)。相反,是一个循环构造,并且可以向其元素询问其参数,以便它可以有效地循环。它在您的示例中这样做,并且该对象不包含元素,因此根本不调用该块。for.listMatchfor

given foo(或者given foo, bar

given只是将其参数作为主题(“it”)并调用关联的语句或块(传入主题)。故事结局。

for foo, bar

for foo, bar只是依次将其每个参数设为主题(并调用关联的语句/块)。再说一遍,故事结束。

for foo

如果for只有一个参数,并且该参数没有显式标记为单数(通过在其前面加上前缀$),则for调用.list该参数,并且对于返回列表中的每个值,将其设置为“it”并调用关联的语句/块,一一。这就是你的场景。再说一遍,故事结束。

但这显然会让你(和莉兹)感到困惑,所以我的答案需要更多一点!


与数组或散列一样,对象Capture(因此Match)可以包含零个或多个元素。在所有这些情况下,对象本身都不是元素

当 Rakoon 不for [] { ... }执行任何操作时,并不感到惊讶,因为[]很明显,它不包含任何元素,而且数组返回自身就好像它本身是一个元素一样,这有点愚蠢,更不用说令人困惑了。

关于什么for Match.new { ... }?它也什么也不做,原因也许很明显——因为它也不包含任何元素。

但你的例子呢?好吧,再说一遍,它什么也不做,再说一遍,这是因为它不包含任何元素。

但是“什么?!?” 你说!匹配对象本身肯定是有用的数据吗?为什么for不像以前那样对待它呢for 42 { ... }?好吧,因为如果你绝对想要那样,那就写given 42 { ... }吧。如果您使用,那么期望 Raku为其参数for寻找一个列表.list含义,而不是单一含义,这意味着在您的问题场景中调用其参数。

那么对象的元素什么?它们是它的对象(如果有的话)。可能有位置的(您可以使用例如 、或 来访问)和命名的(您可以使用例如或 来访问)。Match Matchmatch-object[...].listmatch-object{...}.hash