如何在Erlang中写“a == b?X:Y”?

时间:2011-05-23 04:51:41

标签: erlang

有没有一种在Erlang中编写这样的代码的好方法?

A == B ? X : Y

下面是ruby风格的代码

6 个答案:

答案 0 :(得分:35)

说明

三元运算符_ ? _ : _存在于多种语言中的原因是它们有两个句法类:语句和表达式。由于if-then-else结构通常属于语句类,因此在输入表达式时无法使其工作。因此,您将_ ? _ : _运算符添加到表达式类。

正如另一篇文章所述,您可以a == b ? true : false并撰写a == b,但这并不能解释我们可能a == b ? X : Y任意表达X的一般情况和Y。另请注意,a == b在Erlang中始终为false,因此您可以认为真正要做的是用false替换整个表达式。

幸运的是,与大多数函数式语言一样,Erlang只有一个语法类,表达式。因此,您可以在函数的任何位置使用case a == b of X -> ...; Y -> ... end,包括其他表达式。换句话说,三元_ ? _ : _运算符在Erlang中是多余的,因为case已经有效。

一个例子:

假设我们要返回一个简单的proplist并且我们需要做一些计算

  f() ->
    case a == b of
          true -> 
           [{a, 3},
            {b, <<"YE">>},
            {c, 7}];
          false ->
           [{a, 3},
            {b, <<"YE">>},
            {c, "HELLO!!!"}];
    end.

但由于case构造是一个表达式,我们可以内联它:

  f() ->
    [{a, 3},
     {b, <<"YE">>},
     {c, case a == b of
          true -> 7;
          false -> "HELLO!!!"
         end}].

并完成了这件事。

为什么我不主张使用IF

Erlang中的if .. end构造通常不是您想要的。在这种情况下,您希望仔细检查值a == b,它可以产生两个输出truefalse中的一个。在这种情况下,case - 表达式更直接。如果你必须检查多个不同的测试并选择第一个匹配,那么if会被更好地使用,而我们在这里只需要进行一次测试。

答案 1 :(得分:6)

我们使用这样的宏:

-define(IF(Cond,E1,E2), (case (Cond) of true -> (E1); false -> (E2) end)).

然后在你的代码中写下:

io:format("~s~n", [?IF(a==b, "equal", "not equal")]).

答案 2 :(得分:5)

如果您问的是如何将A == B ? X : Y写成if表达式,那就是

if
    A == B ->
        X;
    true ->    % "true" means "else" here
        Y
end

您也可以将其写为case表达式:

case A == B of
    true ->
        X;
    _Else ->
        Y
end

case A == B of
    true ->
        X;
    false ->
        Y
end

答案 3 :(得分:4)

由于a == b ? true : false映射到a == b,您也可以在Erlang中使用a == b

答案 4 :(得分:1)

您可以像这样使用'if'

foo(A,B) ->
    [1,
     2,
     (if A == B -> 3; true -> 4 end), % A == B ? 3 : 4
     5,
     6].

特别?:表格似乎没有必要。你当然可以使用true / false作为返回值,但我认为你的意思是更一般的形式,因为那将是无用的(A == B做同样的工作)。

答案 5 :(得分:0)

@Gabe's answer是最简洁的,并且(据我所知)惯用语。 C表达式((A==B) ? X : Y)直接映射到Erlang表达式

case A == B of
    true -> X;
    false -> Y
end

但是, 比C版本的代码多得多。你应该把它包装成一个便利函数 - 有人应该告诉我这是否已经存在于Erlang标准库中了!

iff(true, X, Y) -> X;
iff(false, X, Y) -> Y.

然后您的C表达式变为iff(A == B, X, Y)但是,要注意!就像C一样,Erlang急切地评估函数参数。如果XY有副作用或评估费用昂贵,则iff将不等同于内联case表达式。