【问题标题】:Erlang equivalent to if elseErlang 等价于 if else
【发布时间】:2011-05-18 16:34:54
【问题描述】:

我有两部分代码要执行。两者都是条件

if Value1 < N do something 

else if Value1 >= N do something

if Value2 < N do something 

else if Value2 >= N do something

我想在每个语句中执行一个。

if 在 erlang 中如何工作?没有别的了。我使用多个警卫,但看起来我有 4 个 if 语句。 2人一组。

if some condition   
code;

if other condition  
code

end.

我收到语法错误。

【问题讨论】:

  • 我发现如果你依赖于守卫或案例陈述,你可能在 Erlang大部分中“做错了”。您可能应该大部分在 Erlang 中进行模式匹配,以替代守卫和 case 语句。如果没有具体示例,我们无法告诉您是否应该进行案例匹配、保护匹配或模式匹配,但与替代方案相比,模式匹配总是
  • How to implement if-else 的可能重复项

标签: if-statement erlang


【解决方案1】:

Erlang 不允许您在没有 true 语句选项的情况下拥有 if。这是否是真实的陈述或实际的 true 取决于您,但在其他语言中让您的 true 成为 else 是司空见惯的。

if 
    some_condition -> some_code;
    some_other_condition -> some_other_code;
    true -> else_code
end.

请参阅“如果会怎样?” this 页面上的部分以了解更多信息。

【讨论】:

  • 它确实允许有一个没有true 分支的if,并且在这种情况下会在运行时抛出一个异常。
  • 因此,“erlang 不允许玩具在没有 true 语句选项的情况下拥有 if。”。如果没有计算结果为 true,您将获得异常。
  • 但是获得例外是好的。这意味着一个案例没有按照您的计划进行。可以说,捕获所有“else”子句与盲目地捕获所有异常一样糟糕:if X > 0 -> ...; X ...; X =:= 0 -> ...结束。比在最后一个子句中使用 'true' 更加明确和安全。
  • 是的,但是如果你想测试(数学语法,而不是 haskell)4&lt;x&lt;71&lt;x&lt;2-10&lt;x&lt;-7x&gt;=20x&lt;-100 在每个情况下,在任何其他情况下做其他事情(也许是一个人为的例子)。当然-100 &lt;= x &lt;= -10 or -7 &lt;= x &lt;= 1 or 2 &lt;= x &lt;= 4 or 7 &lt;= x &lt; 20 可能更明确,但true(或另一种语言的else)写起来更快,更不容易出错。
  • 在编写时(外观上)不容易出错,而不是在使用时出错。如果您确实在子句中犯了错误,则该错误将被隐藏,直到您的数据在其他地方损坏。让它显式需要更长的时间,但通常在以后阅读时更安全、更容易理解。请参阅您发布的链接,靠近底部,Richard O'Keefe 的引述。
【解决方案2】:

首先,我建议你习惯使用 'case' 语句,因为 'if' 条件仅限于保护表达式:

case custom_call(A) of
  1 -> do1(A);
  2 -> do2(A)
end.

除了 'if' 和 'case' 之外,还有另一种条件执行的方法,从 R13 开始起作用:

  1> N =10.
  10
  2> ((N > 10) andalso more).      
  false
  3> ((N == 10) andalso equals).
  equals

【讨论】:

  • 如果我使用一个案例,当它匹配到某些案例时它不会退出吗?还是会执行该案例并继续尝试匹配第二个?
  • 没有理由盲目地使用 case ... of ... end 而不是 if。如果您的检查可以仅限于守卫,请使用“if”。否则,您将在“案例”中使用空匹配子句使代码复杂化。
  • 好的,但我的问题仍然存在。如果代码执行 if 语句,它会退出吗?还是它会执行语句并转移到下一个守卫?我需要一些代码来根据值执行。然后我有另一种方法,它应该根据另一个值做同样的事情。首先 if 是 Value >= queue:len , else 应该是 Value
  • 如果有 if 或 case,它将匹配第一个,执行它然后离开。只有当它与第一个分支不匹配时,它才会尝试第二个、第三个等。这不像 C 中的带有贯穿子句的“case”或“switch”。
  • 好的,谢谢。因此,在一个案例中使用第一个“if else”,然后在第二个案例中使用下一个“if else”。我需要一个通过执行 2 之一来完成,然后继续下一部分并执行 2 之一。
【解决方案3】:

if 的格式为:

if
    <guard 1> -> <body1> ;
    <guard 2> -> <body2> ;
    ...
end

它以自上而下的顺序(这是定义的)尝试 if 子句中的守卫,直到它到达成功的测试,然后评估该子句的主体,if 表达式返回最后一个的值身体中的表达。所以其他语言中的else 位被嵌入其中。如果没有一个守卫成功,则生成if_clause 错误。一个通用的包罗万象的守卫就是true,它总是成功的,但一个包罗万象的东西可以是任何真实的东西。

case 的格式为:

case <expr> of
    <pat 1> -> <body1> ;
    <pat 2> -> <body2> ;
    ...
end

它的工作原理是首先评估然后尝试将该值与 case-clauses 中的模式以 op-down 顺序(这是定义的)匹配,直到一个匹配,然后该子句的主体是 求值,case 表达式返回正文中最后一个表达式的值。如果没有匹配的模式,则会生成 case_clause 错误。

请注意,ifcase 都是表达式(一切都是表达式),因此它们都必须返回值。这就是如果没有成功/匹配则没有默认值的原因之一。还强迫您涵盖所有选项;这对case 尤其重要。 if 只是 case 的退化案例,所以它继承了它。 Erlang Rationale 中有一些 if 的历史,您可以在 trapexit.org 的用户贡献下找到。

【讨论】:

  • 如何找到“Erlang Rationale 中有一些 if 的历史记录,您可以在 trapexit.org 的用户贡献下找到。”?
【解决方案4】:

请记住,Erlang 中的 if 有一个要返回的值,它是一个表达式。 if 像在 C 或 Java 中一样。

如果你想为一个值做某事,代码应该是这样的;

if
  % do something and get the value
  X >= Val -> Something;
  % for doing something otherwise and get the value
  true -> Else_than_the_Something 
end.

更多详情请参阅Section for the if expression of Erlang Reference Manual

【讨论】:

    猜你喜欢
    • 2017-06-08
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 2018-01-27
    相关资源
    最近更新 更多