如果try{}块中出现多个异常,而try{}块中只有一个CATCH{}块,那么这个CATCH{}块可以捕获任何/所有异常吗?或者我是否需要为每个可能的异常设置一个CATCH{}?
try { CATCH { default { say "seenError" }; }; die "1"; die "2"; die "3" }
seenError
在上面的例子中,哪个“die”语句被捕获了?第一名?如果我想处理每个异常,我需要把每个可能的异常放在一个单独的CATCH{}中吗?
首先:您不需要try
就可以拥有CATCH
块。在Raku编程语言中,CATCH
块可以存在于任何词法范围内。
所以你的例子可以变成:
CATCH {
default { # $_ contains the exception
say .message; # show what the message was
}
}
die "1";
die "2";
die "3";
say "still alive";
如果你像这样运行它,它只会说“1”,暗示只有第一个异常被捕获。这是正确的,因为你没有改变任何情况:异常仍然是活跃的,并将导致你的程序终止。
您需要的是在处理异常后恢复执行。有一种方法:.resume
。它不适用于所有异常,但随后会告诉你它不适用。
将程序更改为:
CATCH {
default {
say .message;
.resume; # continue execution after where exception occurred
}
}
die "1";
die "2";
die "3";
say "still alive";
这将显示“1”、“2”、“3”、“还活着”。
那么< code>try做什么呢?基本上,它为您添加了一个< code>CATCH块,该块将捕获它看到的第一个异常,并将该异常放入< code>$!并返回< code>Nil。您可以将< code>try块视为将致命异常转化为良性故障的一种方式。如果你对失败的原因不感兴趣,就用它。并且< code>try也可以是语句前缀。简而言之:
say try die; # Nil
(请不要忘记接受莉兹的回答。这只是她回答的附录。
正如Liz所指出的:
您不需要< code>try来拥有< code>CATCH块
正如她所暗示的,在使用< code>try时,也不需要< code>CATCH块:
for 1, 2, 3 {
try { print 'something ... '; .&die } or put "seenError: $!"
}
显示:
something ... seenError: 1
something ... seenError: 2
something ... seenError: 3
正如Liz还概述的那样,如果在处理try
d的代码期间抛出异常而不是。恢复
d,或者如果有未处理的失败
,try
捕获异常/失败,将相应的异常放入$!
,并返回Nil
。
我提到这一点是为了介绍最后一个可能感兴趣的选项:< code>trys,这是我为回答从异常处理程序返回值的SOQ而创建的。