Erlang 案例陈述

Posted

技术标签:

【中文标题】Erlang 案例陈述【英文标题】:Erlang case statement 【发布时间】:2014-01-31 18:16:05 【问题描述】:

我有以下 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 之后尝试了一个匿名变量,但仍然不满意。

【问题讨论】:

【参考方案1】:

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

最后一行必须是

_ -> io:format("no match ~p~n",[P])

此外,io:format 返回“ok”。因此,如果 P 不是 x y 或 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.

【讨论】:

我会抛出异常,或者可能只是不检查 x,y,z 以外的任何内容。 Erlang 可以理解地失败,无需过度。 正确。但是如果不检查,您可能会在调用函数之后的某个地方出现错误。 ok,R = fall_velocity(A,B) 可以提前指出错误。 其实这要看是谁调用了这个函数。如果函数是 API 的一部分,那么确实欢迎标记值。但是,如果该函数是代码库深处的内部部分,那么您最终会到处都有 case 语句,不断地检查您自己的代码的错误,这是一个不必要的麻烦。就让它失败吧。 这是很容易检查的事情之一,因此“他们”决定为其添加警告检查。这只是一个警告,因此如果您决定忽略,那么在运行代码时会出现错误。【参考方案2】:

为了明确其他答案的 cmets,这就是我编写该函数的方式:

-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_clause, foo 以及指向此函数其调用者的堆栈跟踪。这也意味着此函数不会因为使用不正确的参数调用而将不正确的值泄漏到其余代码中。

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

【讨论】:

以上是关于Erlang 案例陈述的主要内容,如果未能解决你的问题,请参考以下文章

centos7剽窃安装erlang和rabbitmq成功案例

有大量节点或二进制数据时的 Erlang 消息

Erlang:变量'_'未绑定

如何在Linux下安装Erlang

Erlang - C 和 Erlang

C 和 Erlang:Erlang 端口示例