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

How many exceptions does one CATCH block catch?

如果一个try{}块中出现多个异常,而try{}块中只有一个CATCH{}块,那么这个CATCH{}块是否可以捕获any/all异常?还是我需要一个 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”,暗示只捕获了第一个异常。这是正确的,因为您 NOT 改变了有关情况的任何内容:异常仍然有效,将导致您的程序终止。

你需要的是在异常处理后恢复执行。有一个方法:.resume。它不适用于所有异常,但随后您会被告知它不起作用。

将程序更改为:

CATCH {
    default {
        say .message;
        .resume;  # continue execution after where exception occurred
    }
}
die "1";
die "2";
die "3";
say "still alive";

这将显示“1”、“2”、“3”、“还活着”。

那么try是做什么的呢?基本上,它会为您添加一个 CATCH 块,它将捕获它看到的第一个异常,将异常放在 $! 和 return 和 Nil 中。您可以将 try 块视为将致命异常转变为良性故障的一种方式。如果您对失败的原因不感兴趣,则可以使用它。而try也可以是语句前缀。简而言之:

say try die;  # Nil

(请不要忘记接受 Liz 的回答。这只是她回答的附录。)

正如 Liz 所说:

you do NOT need a try to have a CATCH block

而且,正如她暗示的那样,使用 try:

时也不需要 CATCH
for 1, 2, 3 {
  try { print 'something ... '; .&die } or put "seenError: $!"
}

显示:

something ... seenError: 1
something ... seenError: 2
something ... seenError: 3

如 Liz also 所述,如果在处理正在 tryd 的代码期间抛出异常而不是 .resumed,或者如果有未处理的 Failuretry 捕获 exception/failure,将相应的异常放入 $!,returns Nil.

我提到这个是为了介绍一个可能感兴趣的最后一个选项:trys,这是我为 my answer to the SOQ Returning values from exception handlers 创建的。