【问题标题】:Why use do/else keywords to if in Elixir?为什么在 Elixir 中对 if 使用 do/else 关键字?
【发布时间】:2016-10-25 04:16:12
【问题描述】:

一直在努力学习 Elixir,我有点好奇做单行 if/else 的不同方式。

我从...开始

if left_side_wins?(p, c) do
  {"Humanity", p, c}
else
  {"The Machine", c, p}
end
|> print_winner

... 为任一获胜者正确地管道元组。但是这个不...

if left_side_wins?(p, c), do: {"Humanity", p, c}, else: {"The Machine", c, p}
|> print_winner

...我知道这是因为|> 被认为是else 的一部分,我可以用括号来修复它...

if(left_side_wins?(p, c), do: {"Humanity", p, c}, else: {"The Machine", c, p})
|> print_winner

... 现在可以使用了。对于任一获胜者,元组都会正确地通过管道传送到print_winner

但我也可以使用内联的 do/else/end 块并执行...

if left_side_wins?(p, c) do {"Humanity", p, c} else {"The Machine", c, p} end
|> print_winner

...也可以。

我读过的每个资源都描述了使用do:.., else:.. 格式,但do ... else ... end 似乎更简洁且不易出错。

除了我所看到的之外,它们之间的主要区别是什么?

do: ..., else: ... 似乎是首选,但它不是对运算符优先级更敏感吗?

【问题讨论】:

    标签: elixir


    【解决方案1】:

    其实语法:

    if condition do
    # something
    else 
    # something else
    end
    

    被翻译成if condition, do: , else:

    使用第一个选项更具可读性,并且更符合 Ruby 的语法。使用第二个选项可以为您节省一些不必要的代码行,但在技术上是完全一样的。 关于运算符优先级规则是相同的。关于管道运算符 - 始终在表达式周围使用括号。

    【讨论】:

    • "...总是在表达式周围使用括号"我喜欢这样,好主意!
    【解决方案2】:

    并不是do: else: 是首选。如果你喜欢它就在那里。它们扩展到相同的东西,但是正如您发现的那样,运算符的优先级是不同的。 |> 并不贪心,所以它试图在它的左边得到最小的表达:

    if condition?, do: true_part, else: false_part |> print_winner
    

    这是:

    if condition?, do: true_part, else: (false_part |> print_winner)
    

    这是:

    if condition?, do: true_part, else: print_winner(false_part)
    

    在某些情况下,这可能是您真正想要的。管道运算符成为 else 表达式的一部分。在if do end 语法的情况下。

    if condition? do true_part else false_part end |> print_winner
    

    同理:

    print_winner(if condition? do true_part else false_part end)
    

    样式指南建议始终以“原始值”开始管道链,这样 linters 就会对你大喊大叫。最安全的方法是分配 if 表达式的结果,这会使管道无用:

    winner = if left_side_wins?(p, c), do: {"Humanity", p, c}, else: {"The Machine", c, p}
    print_winner(winner)
    

    或者将 if 表达式带入它自己的函数中:

    def determine_winner({p, c}) do
      if left_side_wins?(p, c), do: {"Humanity", p, c}, else: {"The Machine", c, p}
    end
    
    {p, c}
    |> determine_winner
    |> print_winner
    

    【讨论】:

    • 很好的讨论,谢谢!是否有任何选择比其他选择更不受欢迎,或者它们通常都被接受为“灵丹妙药”并在不同情况下使用?无论如何,“...总是以原始值开始管道链..”和“...将 if 表达式转换为自己的函数”是很棒的条建议。
    • 他们都是灵药。我看到有人争辩说,如果 do 和 else 中只有一个表达式,则应该使用 , do: else: 并在有多个表达式的情况下保留 do else end。但就个人而言,即使是单个表达式,我也会检查看起来更好的东西。如果一行中的所有内容少于 80 个字符,我使用, do: else:,否则使用do else end。查看 Credo linter github.com/rrrene/credo 它会检查您的代码中是否存在此类内容 :) 这是一个很酷的学习工具!
    猜你喜欢
    • 1970-01-01
    • 2017-03-31
    • 2015-05-19
    • 2017-04-11
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    相关资源
    最近更新 更多