处理异常Erlang的引发和捕获之间的区别

时间:2019-02-19 15:51:16

标签: error-handling erlang runtime-error dialyzer

我有一个像下面这样的简单代码来测试Erlang如何处理异常。 ****的参考。

-module(exception).
-export([sum/2]).
-export([is_odd/1]).

sum(A, B) ->
    case is_odd(A) of
    odd ->
        2*A+B;
    Result ->
        Result
    end.


is_odd(A) ->
    case is_integer(A) of
    true ->
        odd;
    _ -> ****({error, "Input error"})
    end.

当我用透析器跑透析器时,它显示警告:

  

exception.erl:9:自上一个版本以来,变量Result永远不会匹配   子句完全覆盖了类型“ odd”

可以通过添加

修复此警告。
  

案例捕获

获得功能乐趣/ 2。

当我用捕获器运行透析器时,透析器成功通过。

我有点想知道抓球。您应该扔或抓住哪种情况?

1 个答案:

答案 0 :(得分:4)

如果使用throw(用于****),则函数is_odd(A)将仅返回一个正常值:原子'odd'。这就是透析器告诉您的:第9行(结果->)的子句永远不匹配。如果is_odd(A)返回一个值,则该值必须为'odd',因此将始终选择第一个子句。

如果编写“ case catch is_odd(A)of ...”,则将捕获所有引发的异常并将其转换为值。在您的情况下,这就是元组{error,“ Input error”}。 (请注意,这是“旧式” catch Expression,通常更喜欢在所有新代码中使用现代的try ... catch ... end。)现在突然之间,又有两个可能的值,子句位于第9行也可以选择,因此透析器不会抱怨。

通常,在相对罕见的情况下使用例外,在常见情况下使用正常的返回值。但是,有时最好将异常用作跳远(“非本地返回”)以摆脱深度递归。