簡體   English   中英

Erlang中function_clause和badarg有什么區別?

[英]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_clausecase_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應該被function_clause覆蓋

但是badarg數學運算時,例如1/0會拋出badarg

在大多數情況下,當帶有警衛的函數定義將拋出function_clause

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM