我有一个像下面这样的简单代码来测试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。
当我用捕获器运行透析器时,透析器成功通过。
我有点想知道抓球。您应该扔或抓住哪种情况?
答案 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行也可以选择,因此透析器不会抱怨。
通常,在相对罕见的情况下使用例外,在常见情况下使用正常的返回值。但是,有时最好将异常用作跳远(“非本地返回”)以摆脱深度递归。