有没有一种在Erlang中编写这样的代码的好方法?
A == B ? X : Y
下面是ruby风格的代码
答案 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}].
并完成了这件事。
Erlang中的if .. end
构造通常不是您想要的。在这种情况下,您希望仔细检查值a == b
,它可以产生两个输出true
或false
中的一个。在这种情况下,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急切地评估函数参数。如果X
或Y
有副作用或评估费用昂贵,则iff
将不等同于内联case
表达式。