在第一个 "once {next}" 块之后,其他相同范围的 "once" 块无法执行
After first "once {next}" block, other same-scoped "once" blocks fail to execute
我最初的计划是使用两个 once {next}
块来跳过文件中的前两行(此处将 a 模拟为多行字符串):
for "A\nB\nC\n".lines() -> $line {
once {next}
once {next}
put $line;
}
但它只跳过了一次迭代而不是两次,输出如下:
B
C
而不是我的预期:
C
显然,单个 once {next}
以某种方式取消了同一范围内所有剩余的 once
块:
my $guard = 3;
loop {
last if $guard-- <= 0;
once { next };
once { put 'A: once ' };
once { put 'A: once again' };
put 'A: many ';
}
$guard = 3;
loop {
last if $guard-- <= 0;
once { put 'B: once ' };
once { next };
once { put 'B: once again' };
put 'B: many ';
}
$guard = 3;
loop {
last if $guard-- <= 0;
once { put 'C: once ' };
once { put 'C: once again' };
once { next };
put 'C: many ';
}
输出:
A: many
A: many
B: once
B: many
B: many
C: once
C: once again
C: many
C: many
(此处的示例代码是 https://docs.raku.org/language/control#once 处代码的修改版本)。
这是一个错误还是我误解了once {next}
?
once
构造语义与闭包克隆相关联;由于 for
是根据 map
定义的,我们可以认为 for
循环的块就像一个闭包,每个循环克隆一次,并且该克隆用于所有迭代循环。 once
块的 运行 仅在第一次调用该闭包克隆时完成。也就是说,它是闭包级别的 属性,而不是 once
块本身之一。
完全相同的语义适用于 state
变量初始值设定项,它们以相同的方式定义(即,它们具有 once
语义)。因此,这也表现出相同的行为:
for "A\nB\nC\n".lines() -> $line {
state $throwaway-a = next;
state $throwaway-b = next; # this `next` never runs
put $line;
}
可以选择其他语义,但是每个 once
(以及每个 state
变量)指示器意味着它们中的每一个都需要一个额外的状态。
就最初的问题而言,更清晰的解决方案是:
for "A\nB\nC\n".lines().skip(2) -> $line {
put $line;
}
我最初的计划是使用两个 once {next}
块来跳过文件中的前两行(此处将 a 模拟为多行字符串):
for "A\nB\nC\n".lines() -> $line {
once {next}
once {next}
put $line;
}
但它只跳过了一次迭代而不是两次,输出如下:
B
C
而不是我的预期:
C
显然,单个 once {next}
以某种方式取消了同一范围内所有剩余的 once
块:
my $guard = 3;
loop {
last if $guard-- <= 0;
once { next };
once { put 'A: once ' };
once { put 'A: once again' };
put 'A: many ';
}
$guard = 3;
loop {
last if $guard-- <= 0;
once { put 'B: once ' };
once { next };
once { put 'B: once again' };
put 'B: many ';
}
$guard = 3;
loop {
last if $guard-- <= 0;
once { put 'C: once ' };
once { put 'C: once again' };
once { next };
put 'C: many ';
}
输出:
A: many
A: many
B: once
B: many
B: many
C: once
C: once again
C: many
C: many
(此处的示例代码是 https://docs.raku.org/language/control#once 处代码的修改版本)。
这是一个错误还是我误解了once {next}
?
once
构造语义与闭包克隆相关联;由于 for
是根据 map
定义的,我们可以认为 for
循环的块就像一个闭包,每个循环克隆一次,并且该克隆用于所有迭代循环。 once
块的 运行 仅在第一次调用该闭包克隆时完成。也就是说,它是闭包级别的 属性,而不是 once
块本身之一。
完全相同的语义适用于 state
变量初始值设定项,它们以相同的方式定义(即,它们具有 once
语义)。因此,这也表现出相同的行为:
for "A\nB\nC\n".lines() -> $line {
state $throwaway-a = next;
state $throwaway-b = next; # this `next` never runs
put $line;
}
可以选择其他语义,但是每个 once
(以及每个 state
变量)指示器意味着它们中的每一个都需要一个额外的状态。
就最初的问题而言,更清晰的解决方案是:
for "A\nB\nC\n".lines().skip(2) -> $line {
put $line;
}