此循环永不停止:
class CX::Vaya does X::Control {
has $.message
}
loop {
once {
CX::Vaya.new( message => "I messed up!" ).throw;
}
last;
CONTROL {
default {
say "Controlled { .^name }: { .message }"
}
}
}
Run Code Online (Sandbox Code Playgroud)
它一直在写
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
...
Run Code Online (Sandbox Code Playgroud)
可能once有点,因为最后一个CONTROL移相器确实完成了:
loop { say "Hey"; last; CONTROL { default: .message.say } }
# OUTPUT: «Hey?<last control exception>?»
Run Code Online (Sandbox Code Playgroud)
但是我不确定。
Jon*_*ton 13
Perl 6中的循环流控制是使用控制异常实现的。因此,last实际上是引发了CX::Last控制异常。由于该CONTROL块使用default,因此它捕获了CX::Lastthrow last,这意味着控制永远不会移出循环。
解决方法是改为使用来指定要捕获的控件异常when:
loop {
once {
CX::Vaya.new( message => "I messed up!" ).throw;
}
last;
CONTROL {
when CX::Vaya {
say "Controlled { .^name }: { .message }"
}
}
}
Run Code Online (Sandbox Code Playgroud)
乔纳森说什么。
更详细地:
P6的默认控制流程是,下一条语句将紧随当前语句。因此,say 42; say 99;默认情况下先执行say 42,然后再执行say 99。
P6具有先进且广泛使用的异常系统,该系统用于处理此一语句的默认控制流的异常,然后立即执行以下语句。这不仅仅是错误。
默认控制流的任何异常都称为异常。许多是错误异常。但是还有另一类,即控制流异常或简称控制异常。例如,来自例程/块的显式或隐式return/ leave是控制异常。(原则上。实际上,编译器/优化器会在适当的情况下忽略某些这种机制。)
A last是控件异常。它引发控制异常CX::Last。其消息有效载荷为"last control exception"。您正在看到该消息。
甲CONTROL如果控制异常适用于它的包含块被输入块。它可以处理传递的异常,也可以不处理。如果处理,则控制将继续执行其后的语句。如本例所示,如果该CONTROL块位于循环的末尾,则下一条语句将是隐式的next(另一个控制异常),并且循环将重新开始。
该代码CONTROL { default { say "Controlled { .^name }: { .message }" }处理所有控制异常,包括由引发的异常last。因此它将打印其消息,然后循环继续。(无限地。)
在代码中loop { say "Hey"; last; CONTROL { default: .message.say } } # OUTPUT: «Hey?<last control exception>?»,该CONTROL块的确显示了异常的消息,但没有处理。(default:只是一个标签,I'm-a-label:与之没有区别,并且与不相关default { ... }。)因此,last控制异常不是由您的代码处理,而是由打破循环的默认语言处理来处理。
| 归档时间: |
|
| 查看次数: |
88 次 |
| 最近记录: |