[英]What's the difference between function_clause and badarg in Erlang?
有時我得到badarg
而不是function_clause
但是我看不到決定哪一個會出現的規則。
據我了解, function_clause
時,沒有功能的實現匹配給定的參數被拋出。 關於badarg
文檔說
該參數的數據類型錯誤,或者形式錯誤。
這似乎涵蓋了function_clause
條件......
例如
lists:flatten(3).
throws子句錯誤,而類型肯定不匹配。
函數子句是具有不同參數模式/保護的定義的一部分,如
func({X, Y}) -> ...;
func(X) when X > 10 -> ...;
func(_) -> ...
function_clause
表示它們都不匹配。 有類似的if_clause
和case_clause
。 對於單個參數的flatten
, 只有一個子句
flatten(List) when is_list(List) ->
do_flatten(List, []).
哪個不匹配3
,這就是你得到function_clause
。
所以
有時我得到badarg而不是function_clause但是我看不到決定哪一個會出現的規則
這基本上是一個實現細節,您在調試該函數的實現時應該只關心它。
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>
這是官方解釋:
不好的論點。 該參數的數據類型錯誤,或者形式錯誤。
在評估函數調用時,找不到匹配的函數子句。
有時badarg應該被function_clause覆蓋
但是badarg
數學運算時,例如1/0
會拋出badarg
在大多數情況下,當帶有警衛的函數定義將拋出function_clause
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.