边救边抓

Rescuing and catching at the same time

如果我既想挽救一个潜在的错误又想捕捉一个潜在的抛出,我应该如何嵌套它们?下面这两个是不是等价的,只是喜好问题?

begin
  catch(:some_throw) do
    ...
  end
rescue SomeError
  ...
end


catch(:some_throw) do
  begin
    ...
  rescue SomeError
    ...
  end
end

这是一个 opinion-based 的问题,可以用任何一种方式争论。所以,在我看来...

如果您打算通过 throw return 一个值,那么,第二个选项似乎很有用,因为它会让您 rescue 一个错误和 throw 某种错误默认值。

即使您使用 throwcatch 只是为了管理循环迭代并在某些条件下打破它,第二个选项似乎仍然更具可读性并将所有逻辑封装在 catch块。

它们并不完全等同。对于第一个选项,catch 只会拦截 begin 子句中抛出的值,而第二个选项也包括来自 rescue 的值。


话虽这么说,如果你是这种情况,当两者相等时(也就是你不在 rescue 子句中抛出 :some_throw):

  • 第一种选择的论据是我们倾向于认为 begin - rescue 块包含 "regular" 语句。 throw - catch 很少使用并且具有 non-error 语义更多 "regular"-y.

  • 第二种选择的论点是应该努力在 begin - rescue 子句中包含最少数量的代码(仅可能失败的代码)。

就个人而言,我更喜欢第一个。