【问题标题】:What is the difference between "if" statements with "then" at the end?“if”语句末尾带有“then”有什么区别?
【发布时间】:2019-07-22 22:04:34
【问题描述】:

当我们将then 放在if 语句的末尾时,这两个Ruby if 语句有什么区别?

if(val == "hi") then
  something.meth("hello")
else
  something.meth("right")
end

if(val == "hi")
  something.meth("hello")
else
  something.meth("right")
end

【问题讨论】:

    标签: ruby


    【解决方案1】:

    then 是一个分隔符,帮助 Ruby 识别条件和表达式的真实部分。

    if条件then真部分else假部分end

    then 是可选的除非你想在一行中写一个if 表达式。对于跨越多行的 if-else-end,换行符充当分隔符,将条件与 true 部分分开

    # can't use newline as delimiter, need keywords
    puts if (val == 1) then '1' else 'Not 1' end
    
    # can use newline as delimiter
    puts if (val == 1)
      '1'
    else
      'Not 1'
    end
    

    【讨论】:

    • 在 Ruby 中,if 是一个表达式,而不是一个语句。事实上,everything 是一个表达式,没有语句。因此,你的两个例子最好写成puts if val == 1 then '1' else 'Not 1' end
    • @Jorg - 对。我需要一些时间才能消除 C 的岁月。 :)
    • 在 ruby​​ 2.1.2 中,puts if (1 == 1) then '1' else 'not 1' end 引发 syntax error, unexpected keyword_then, expecting end-of-input,除非您将 if 语句放在括号中 puts (if (1 == 1) then '1' else 'not 1' end)
    • 为了完整起见,对于单行 if 表达式,您应该支持 ternary operatorputs(1==1 ? '1' : 'Not 1')
    【解决方案2】:

    这里有一个与您的问题没有直接关系的快速提示:在 Ruby 中,没有 if 语句之类的东西。事实上,在 Ruby 中,根本没有语句Everything 是一个表达式。 if 表达式返回在所采用的分支中计算的最后一个表达式的值。

    所以,不用写了

    if condition
      foo(something)
    else
      foo(something_else)
    end
    

    最好写成

    foo(
      if condition
        something
      else
        something_else
      end
    )
    

    或作为单线

    foo(if condition then something else something_else end)
    

    在你的例子中:

    something.meth(if val == 'hi' then 'hello' else 'right' end)
    

    注意:Ruby 也有一个三元运算符 (condition ? then_branch : else_branch),但这是完全没有必要的,应该避免。在像 C 这样的语言中需要三元运算符的唯一原因是因为在 C 中 if 是一个语句,因此不能返回值。您需要三元运算符,因为它是一个表达式,并且是从条件返回值的唯一方法。但是在 Ruby 中,if 已经是一个表达式,所以真的不需要三元运算符。

    【讨论】:

    • 在 Ruby 中,有很多方法可以达到相同的目标。我个人喜欢三元运算符。我觉得它简洁易读:)
    • 我们在构建系统中广泛使用 ruby​​,我发现第一种语法对于来自其他语言的开发人员来说更容易理解。
    • 可读性对代码质量至关重要。在参数列表中嵌套多行分支结构(无论是语句还是表达式)是荒谬的。它需要大量的扫描和考虑才能对正在发生的事情有一个高层次的了解。花一些额外的击键和失去一点 DRY 使您的代码更具可读性和可支持性。潜入(简单)三元运算符不会违反可读性,也不会在拉取请求中被拒绝。
    【解决方案3】:

    then 仅在您想将if 表达式写在一行时才需要:

    if val == "hi" then something.meth("hello")
    else something.meth("right")
    end
    

    您示例中的括号并不重要,您可以在任何一种情况下跳过它们。

    详情请参阅Pickaxe Book

    【讨论】:

      【解决方案4】:

      我喜欢在多行if/else 上使用then 的唯一一次(是的,我知道这不是必需的)是当if 有多个条件时,如下所示:

      if some_thing? ||
        (some_other_thing? && this_thing_too?) ||
        or_even_this_thing_right_here?
      then
        some_record.do_something_awesome!
      end
      

      我发现它比以下任何一个(完全有效的)选项都更具可读性:

      if some_thing? || (some_other_thing? && this_thing_too?) || or_even_this_thing_right_here?
        some_record.do_something_awesome!
      end
      
      # or
      
      if some_thing? ||
        (some_other_thing? && this_thing_too?) ||
        or_even_this_thing_right_here?
        some_record.do_something_awesome!
      end
      

      因为它提供了if 的条件和条件评估为true 时要执行的块之间的可视化描述。

      【讨论】:

        【解决方案5】:

        根本没有区别。

        而且,仅供参考,您的代码可以优化为

        something.meth( val == 'hi' ? 'hello' : 'right' )
        

        【讨论】:

        • 缩短,而不是“优化”?
        • 较短但不太清晰。我从不在快速原型之外使用这种结构。
        • 很好地使用了三元运算符!
        猜你喜欢
        • 2016-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-07
        相关资源
        最近更新 更多