Erlang案例陈述

Erlang案例陈述,erlang,erlang-shell,erl,Erlang,Erlang Shell,Erl,我有下面的Erlang代码,当我试图编译它时,它给出如下警告,但这是有意义的。函数需要两个参数,但我需要匹配“其他所有参数”,而不是x、y或z -module(crop). -export([fall_velocity/2]). fall_velocity(P, D) when D >= 0 -> case P of x -> math:sqrt(2 * 9.8 * D); y -> math:sqrt(2 * 1.6 * D); z -> math:sqrt(2

我有下面的Erlang代码,当我试图编译它时,它给出如下警告,但这是有意义的。函数需要两个参数,但我需要匹配“其他所有参数”,而不是x、y或z

-module(crop).
-export([fall_velocity/2]).

fall_velocity(P, D) when D >= 0 ->
case P of
x -> math:sqrt(2 * 9.8 * D);
y -> math:sqrt(2 * 1.6 * D);
z -> math:sqrt(2 * 3.71 * D);
(_)-> io:format("no match:~p~n")
end.

crop.erl:9: Warning: wrong number of arguments in format call. 

我尝试在io:format之后使用匿名变量,但仍然不满意。

以您使用的格式~p。它的意思是——打印值。因此,必须指定要打印的值

案例的最后一行必须是

_ -> io:format("no match ~p~n",[P])
此外,io:format返回“ok”。因此,如果P不是xy或z,函数将返回“ok”而不是数值。我建议返回带标签的值,以区分正确和错误返回。有点

fall_velocity(P, D) when D >= 0 ->
case P of
x -> {ok,math:sqrt(2 * 9.8 * D)};
y -> {ok,math:sqrt(2 * 1.6 * D)};
z -> {ok,math:sqrt(2 * 3.71 * D)};
Otherwise-> io:format("no match:~p~n",[Otherwise]),
            {error, "coordinate is not x y or z"}
end.

为了明确对另一个答案的注释,我将这样编写该函数:

-module(crop).
-export([fall_velocity/2]).

fall_velocity(P, D) when D >= 0 ->
    case P of
        x -> math:sqrt(2 * 9.8 * D);
        y -> math:sqrt(2 * 1.6 * D);
        z -> math:sqrt(2 * 3.71 * D)
    end.
也就是说,不要在case表达式中处理错误的参数。如果有人将
foo
作为参数传递,您将得到错误
{case_子句,foo}
,以及指向此函数及其调用方的堆栈跟踪。这也意味着该函数不能因使用不正确的参数调用而将不正确的值泄漏到代码的其余部分


在另一个答案中返回
{ok,Result}{error,error}
同样有效。您需要选择最适合您的情况的变体。

我会抛出一个异常,或者干脆不检查x、y、z以外的任何内容。Erlang的失败是可以理解的,不需要过度。但若不进行检查,您可能会在调用函数之后的某个地方出现错误。{ok,R}=fall_velocity(A,B)可能会更早地指出错误。事实上,这取决于调用函数的人。如果函数是API的一部分,那么标记值确实是受欢迎的。但是,如果函数是代码库深处的一个内部部分,那么最终到处都是case语句,不断地检查自己的代码,这是一个不必要的麻烦。让它失败吧。这是很容易检查的事情之一,所以“他们”决定为它添加一个警告检查。这只是一个警告,因此如果您决定忽略,那么在运行代码时将出现错误。