提问者:小点点

一个CATCH块可以捕获多少个异常?


如果try{}块中出现多个异常,而try{}块中只有一个CATCH{}块,那么这个CATCH{}块可以捕获任何/所有异常吗?或者我是否需要为每个可能的异常设置一个CATCH{}?

try { CATCH { default { say "seenError" }; }; die "1"; die "2"; die "3" }
seenError

在上面的例子中,哪个“die”语句被捕获了?第一名?如果我想处理每个异常,我需要把每个可能的异常放在一个单独的CATCH{}中吗?


共2个答案

匿名用户

首先:您不需要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还概述的那样,如果在处理tryd的代码期间抛出异常而不是。恢复d,或者如果有未处理的失败try捕获异常/失败,将相应的异常放入$!,并返回Nil

我提到这一点是为了介绍最后一个可能感兴趣的选项:< code>trys,这是我为回答从异常处理程序返回值的SOQ而创建的。