【问题标题】:Erlang if else statementErlang if else 语句
【发布时间】:2012-09-13 01:23:06
【问题描述】:

我正在尝试做一个方法来检查两个原子的值,如果它们彼此等价,它就会说它是假的,反之,如果它们不等价,它就会是真的。

我的代码如下所示:

b_not(X, Y) ->
if
    X=:=Y ->
        false;
else
        true;
end.

这里我的方法的名称是“b_not”,它代表 boolean_not。如果 X 完全等于 Y,我会检查 if 语句,它会说假。好吧,我可以单独做那部分。 但是当我尝试做出 else 语句时,我的问题就出现了。 我似乎没有得到这部分,我试图在互联网上搜索,但我似乎没有得到它。 所以如果你能告诉我 if-else-statement 在 Erlang 中是如何工作的,我会很高兴的!

谢谢阿列克谢!

【问题讨论】:

标签: functional-programming erlang if-statement


【解决方案1】:

我对 Erlang 比较陌生,但该语言的设计目的不是按照您描述的方式工作。有一个 if 构造,但我不相信它经常被使用。

相反,您所描述的可以使用模式匹配来实现:

b_not(_X, _X) -> false;
b_not(_, _) -> true.

下划线模式匹配表示通配符;以下划线开头的模式匹配意味着您不打算在函数中使用该值,但您确实关心匹配本身。

所以第一个模式匹配意味着“我不打算将 _X 用于任何事情,但两个值必须相同。”

第二个模式匹配意味着“这些是一次性值,可以是任何值。”

许多函数都使用多个参数模式定义,Erlang 会为您决定哪些模式与调用匹配。

在这种情况下,如果两次传递相同的值,无论是整数、原子、列表还是任何其他类型,都会匹配第一个模式并返回 false。否则,匹配第二个模式。

这只是因为模式是按此顺序定义的;如果它们被颠倒过来,任何参数都会导致结果为真。

插图:

16> foo:b_not(3, 3).
false
17> foo:b_not(3, 4).
true
19> foo:b_not(3, 3.0).
true
20> foo:b_not(match, match).
false
21> foo:b_not(match, nomatch).
true
22> foo:b_not([1, 2], [1, 2]).
false
23> foo:b_not([1, 2], [1, 2, 3]).
true

【讨论】:

  • 您不会在此处使用 _X,因为 X 在另一个参数中使用。 _ 应该表示它根本没有被使用。使用它的唯一原因是当您匹配更复杂的结构时,例如元组或列表。
  • Lukas,除非我没有理解您的观点,否则您需要 _X 作为两个参数来断言它们是相同的(尽管 Emil 的答案更好;我什至没有考虑 =/=)。
  • 重点是你应该有 b_not(X,X),而不是 b_not(_X,_X)。第二个中的 _X 表示未使用该变量,显然不是这种情况。
  • 使用下划线意味着我没有在正文中使用它。来自参考手册:“以下划线 (_) 开头的变量,例如 _Height,是普通变量,不是匿名的。但是编译器会忽略它们,因为它们不会为未使用的变量生成任何警告。”
  • 当然可以这样使用,我的意思是你不应该因为它会使任何阅读代码的人感到困惑。但也许这只是与我一起编程的人。
【解决方案2】:

这就是=/= 运算符的作用!

b_not(X, Y) -> X =/= Y.

我能理解您对if 语句的困惑。您应该真正阅读手册中的ifguards,因为if 像在许多其他语言中一样工作。这是在 Erlang 中实现它的一种方法(但“如果为真,则为真”是一种反模式,所以不要完全这样做):

if
  X =/= Y -> true;
  X =:= Y -> false
end

请注意,当其中一个守卫(箭头左侧)计算为true 原子时,if 语句将计算为该箭头后面的表达式。没有else 子句,但您可以通过将true 放在箭头前来自己发明:

if
  X =/= Y -> true;
  true -> false
end

这不是很直观,尤其是对于来自其他语言背景的人来说,我想这是模式匹配通常比if 表达式更受欢迎的原因之一。

为了完整起见,请阅读case expression。它用于在函数体内进行模式匹配:

case X of
  Y -> false;   % X equals Y
  _ -> true     % Everything else, i.e., X is not Y
end

【讨论】:

    猜你喜欢
    • 2019-04-09
    • 2017-02-05
    • 2015-07-06
    • 2012-08-05
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多