Elixir - 尝试/捕捉vs尝试/救援?

Gav*_*vin 21 elixir

背景

双方try/rescuetry/catch在花好月圆错误处置技术.根据引言指南中的相应章节.

可以使用try/rescue构造来挽救错误

另一方面,

throwcatch被保留用于它在哪里不可能的,除非通过使用检索的值的情况throwcatch.

疑惑

rescue对错误有一个简短的了解.虽然catch是任何价值.

然而,

  • 我什么时候应该使用Elixir中的错误处理机制?
  • 它们之间有什么区别?
  • 我应该如何选择一个用于特定用例?
  • 究竟是什么'除非使用throwcatch' ?, 否则无法检索值的情况

The*_*Anh 24

这是一个很好的问题.经过一番研究.

  • 它们之间的细节有何不同?

    何塞的答案:

主要是,您应该使用throw控制流和保留raise错误,这些错误发生在开发人员错误或特殊情况下.

在Elixir中,这种区别相当理论化,但它们在某些语言中很重要,例如Ruby,其中使用控制流的错误/异常是昂贵的,因为创建异常对象和回溯是昂贵的.

  • 我应该如何选择一个用于特定用例?

请检查这个答案哪些情况需要Elixir中的throw catch

不久:

raise/rescue

考虑提升/救援是明确关于异常处理(程序员错误,错误环境等一些意外情况).

throw/catch

在您预期失败的地方很有用.经典的例子是:

最后一个:

  • 究竟是什么'除非使用throw和catch'否则无法检索值的情况?

假设您正在尝试从由a监督的进程中运行一些代码,Supervisor但该进程因意外原因而死亡.

try do
IO.inspect MayRaiseGenServer.maybe_will_raise
rescue
  RuntimeError -> IO.puts "there was an error"
end
Run Code Online (Sandbox Code Playgroud)

MayRaiseGenServer由a监督Supervisor并由于某种原因引发了错误:

try do
IO.inspect MayRaiseGenServer.maybe_will_raise # <- Code after this line is no longer executed
Run Code Online (Sandbox Code Playgroud)

然后你可以在这里使用catch异常:

try do
  IO.inspect MayRaiseGenServer.maybe_will_raise
catch
  :exit, _ -> IO.puts "there was an error"
end
Run Code Online (Sandbox Code Playgroud)

好的,希望能够澄清我们正在寻找的东西.


Dim*_*gog 13

其他答案已经涵盖了raise对比的用法throw.

我会形容力学如何使用一个表来处理每一个特殊情况:

creating | handling with  | where y is
-----------------------------------------------------
raise x  | rescue y       | %RuntimeError{message: x}
error(x) | rescue y       | %ErlangError{original: x}
throw x  | catch y        | x
exit(x)  | catch :exit, y | x
Run Code Online (Sandbox Code Playgroud)

error(x)实际上在哪里:erlang.error(x).

除此之外,两者rescuecatch/1(用1个参数捕获)只是一个语法糖.所有4案件以上可与处理catch/2:

creating | handling with | where y is | and z is
-----------------------------------------------------------------
raise x  | catch y, z    | :error     | %RuntimeError{message: x}
error(x) | catch y, z    | :error     | x
throw x  | catch y, z    | :throw     | x
exit(x)  | catch y, z    | :exit      | x
Run Code Online (Sandbox Code Playgroud)

注意不对称的处理raise,并errorrescue主场迎战catch/2:x包装到%ErlangErrorrescue被使用,但不与catch/2.

  • 显示所有案例的表格太棒了.我总是对救援/捕获感到困惑,事实上你可以使用catch/1或catch/2.这清除了它.谢谢! (4认同)