Erlang中除以零的精确异常类型

Posted

技术标签:

【中文标题】Erlang中除以零的精确异常类型【英文标题】:Precise exception type for division by zero in Erlang 【发布时间】:2018-12-13 18:35:25 【问题描述】:

我想捕捉零除错误,但不知道我应该为此写哪个确切的模式

Result = try 5/0 catch 'EXIT',badarith,_ -> 0.

当我通过以下方式捕获所有异常时它会起作用

Result = try 5/0 catch _:_ -> 0.

但第一个例子给出了

**异常错误:计算算术表达式时出错

那么如何正确捕捉零除法

【问题讨论】:

【参考方案1】:

你可以使用我从http://learnyousomeerlang.com/errors-and-exceptions得到的这段代码

catcher(X,Y) ->
  case catch X/Y of
   'EXIT', badarith,_ -> "uh oh";
   N -> N
  end.

6> c(exceptions).
ok,exceptions
7> exceptions:catcher(3,3).
1.0
8> exceptions:catcher(6,3).
2.0
9> exceptions:catcher(6,0).
"uh oh"

catcher(X, Y) -> 
  try 
   X/Y 
  catch 
   error:badarith -> 0 
  end. 

【讨论】:

是的,这个可行,但是如何使用上面的表达式达到相同的结果? @MostWanted 编辑了答案 - exept(X, Y) -> try X/Y catch error:badarith -> 0 end.【参考方案2】:

如果您对抛出的确切异常感到好奇,您总能通过这种方式找到

1> try 5/0 catch Class:Reason -> Class, Reason end.
error,badarith
2> try 5/0 catch error:badarith -> ok end.
ok
3> try hd(ok), 5/0 catch error:badarith -> ok end.
** exception error: bad argument
4> try hd(ok), 5/0 catch Class2:Reason2 -> Class2, Reason2 end.
error,badarg
5> try hd(ok), 5/0 catch error:badarg -> ok end.                 
ok

顺便说一句,你现在不应该在大多数情况下使用catch 表达式。它被认为是过时的表达式,主要是为了向后兼容而保留,很少有特殊用途。

【讨论】:

非常感谢!您能否还提供一个现在使用的正确方法的示例,而不是 catch 或链接到一些提到这一事实的文档? @MostWanted 我的意思是你应该使用try ... catch ... end 而不是单独使用catch。当您单独使用catch 时,您会错过异常类。 try ... catch ... end 允许您捕获您期望并打算捕获的唯一异常并让另一个异常抛出。如果使用catch,则必须使用erlang:raise/3 重新抛出不需要的异常。

以上是关于Erlang中除以零的精确异常类型的主要内容,如果未能解决你的问题,请参考以下文章

模数返回除以零异常

在 M0+ 设备上除以零异常

从dao层查出的数据到页面时数值都是零的异常

C++异常如何写

C++异常如何写

C++ 高级教程:C++ 异常处理