function_clause 和 Erlang 中的 badarg 有什么区别?
What's the difference between function_clause and badarg in Erlang?
有时我得到的是 badarg
而不是 function_clause
,但我看不到确定要显示哪一个的规则。
据我了解,当没有函数的实现与给定参数匹配时,将抛出 function_clause
。关于 badarg
文档说
The argument is of wrong data type, or is otherwise badly formed.
function_clause
条件似乎涵盖了...
例如
lists:flatten(3).
抛出子句错误,而类型肯定不匹配。
函数子句是具有不同参数 patterns/guards 的定义的一部分,如
func({X, Y}) -> ...;
func(X) when X > 10 -> ...;
func(_) -> ...
function_clause
表示其中 none 个匹配。还有类似的if_clause
和case_clause
。对于具有单个参数的 flatten
有 only one clause
flatten(List) when is_list(List) ->
do_flatten(List, []).
与 3
不匹配,这就是你得到 function_clause
的原因。
所以
Sometimes I get badarg instead of function_clause but I cannot see the rule that would determine which one is going to appear
这基本上是一个实现细节,您只应在调试该函数的实现时关心它。
1> F = fun({X,L}) -> X + hd(L) end.
#Fun<erl_eval.7.91303403>
2> catch(F(5)). % 5 is not a tuple, so there is no clause in F definition which allow any evaluation
{'EXIT',{function_clause,[{erl_eval,'-inside-an-interpreted-fun-',
[5],
[]},
{erl_eval,eval_fun,6,[{file,"erl_eval.erl"},{line,829}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,437}]},
{shell,exprs,7,[{file,"shell.erl"},{line,686}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
3> catch(F({5,6})). % in the tuple, 6 is not a list, it is a bad argument for erlang:hd/1
{'EXIT',{badarg,[{erlang,hd,[6],[]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,684}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,480}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,437}]},
{shell,exprs,7,[{file,"shell.erl"},{line,686}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
4> catch(F({5,[a]})). % now the error is detected in the addition you get a badarith
{'EXIT',{badarith,[{erlang,'+',[5,a],[]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,684}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,437}]},
{shell,exprs,7,[{file,"shell.erl"},{line,686}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
5> catch(F({5,[6]})).
11
6>
官方解释如下:
巴达格
错误的论点。参数的数据类型错误,或者格式不正确。
function_clause
计算函数调用时未找到匹配的函数子句。
有时 badarg 应该被 function_clause
覆盖
但是当做数学运算时,例如1/0
会抛出badarg
在大多数情况下,当带有 guard 的函数定义将抛出 function_clause
有时我得到的是 badarg
而不是 function_clause
,但我看不到确定要显示哪一个的规则。
据我了解,当没有函数的实现与给定参数匹配时,将抛出 function_clause
。关于 badarg
文档说
The argument is of wrong data type, or is otherwise badly formed.
function_clause
条件似乎涵盖了...
例如
lists:flatten(3).
抛出子句错误,而类型肯定不匹配。
函数子句是具有不同参数 patterns/guards 的定义的一部分,如
func({X, Y}) -> ...;
func(X) when X > 10 -> ...;
func(_) -> ...
function_clause
表示其中 none 个匹配。还有类似的if_clause
和case_clause
。对于具有单个参数的 flatten
有 only one clause
flatten(List) when is_list(List) ->
do_flatten(List, []).
与 3
不匹配,这就是你得到 function_clause
的原因。
所以
Sometimes I get badarg instead of function_clause but I cannot see the rule that would determine which one is going to appear
这基本上是一个实现细节,您只应在调试该函数的实现时关心它。
1> F = fun({X,L}) -> X + hd(L) end.
#Fun<erl_eval.7.91303403>
2> catch(F(5)). % 5 is not a tuple, so there is no clause in F definition which allow any evaluation
{'EXIT',{function_clause,[{erl_eval,'-inside-an-interpreted-fun-',
[5],
[]},
{erl_eval,eval_fun,6,[{file,"erl_eval.erl"},{line,829}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,437}]},
{shell,exprs,7,[{file,"shell.erl"},{line,686}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
3> catch(F({5,6})). % in the tuple, 6 is not a list, it is a bad argument for erlang:hd/1
{'EXIT',{badarg,[{erlang,hd,[6],[]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,684}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,480}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,437}]},
{shell,exprs,7,[{file,"shell.erl"},{line,686}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
4> catch(F({5,[a]})). % now the error is detected in the addition you get a badarith
{'EXIT',{badarith,[{erlang,'+',[5,a],[]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,684}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,437}]},
{shell,exprs,7,[{file,"shell.erl"},{line,686}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
5> catch(F({5,[6]})).
11
6>
官方解释如下:
巴达格
错误的论点。参数的数据类型错误,或者格式不正确。
function_clause
计算函数调用时未找到匹配的函数子句。
有时 badarg 应该被 function_clause
覆盖但是当做数学运算时,例如1/0
会抛出badarg
在大多数情况下,当带有 guard 的函数定义将抛出 function_clause