【问题标题】:How do I use the conditional operator (? :) in Ruby?如何在 Ruby 中使用条件运算符 (? :)?
【发布时间】:2011-05-14 06:26:21
【问题描述】:

条件运算符 (? :) 在 Ruby 中是如何使用的?

例如,这是正确的吗?

<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>

【问题讨论】:

  • 是的,我认为,但我也认为您可以通过以下方式实现:question=question[0,20] 如果它小于 20,它不会改变它。
  • 如果长度大于 20,我还需要添加一个 '...'
  • 小心在给定列中盲目地截断一行。您最终可以在中途删掉一个单词,然后附加省略号('...'),这看起来很糟糕。相反,寻找附近的标点符号或空白字符,并在此处截断。只有当附近没有更好的断点时,才应该截断中间词。

标签: ruby ternary-operator conditional-operator


【解决方案1】:

最简单的方法:

param_a = 1
param_b = 2

result = param_a === param_b ? 'Same!' : 'Not same!'

由于param_a 不等于param_b,那么result 的值将是Not same!

【讨论】:

    【解决方案2】:

    代码condition ? statement_A : statement_B相当于

    if condition == true
      statement_A
    else
      statement_B
    end
    

    【讨论】:

      【解决方案3】:

      @pst 给出了一个很好的答案,但我想提一下,在 Ruby 中,三元运算符写在一行上是为了在语法上是正确的,这与 Perl 和 C 不同的是,我们可以将它写在多行上:

      (true) ? 1 : 0
      

      通常,如果您尝试将其拆分为多行,Ruby 会引发错误,但您可以在行尾使用\ 行继续符号,Ruby 会很高兴:

      (true)   \
        ? 1    \
        : 0
      

      这是一个简单的示例,但在处理较长的行时非常有用,因为它可以使代码布局合理。

      也可以通过将运算符放在最后一行来使用不带行继续字符的三进制,但我不喜欢也不推荐它:

      (true) ?
        1 :
        0
      

      我认为随着条件测试和/或结果变长,这会导致代码非常难以阅读。

      我读过 cmets 说不要使用三元运算符,因为它令人困惑,但这是不使用某些东西的坏理由。按照同样的逻辑,我们不应该使用正则表达式、范围运算符('..' 和看似未知的“触发器”变体)。正确使用它们是强大的,所以我们应该学会正确使用它们。


      为什么要在true 周围加上括号?

      考虑 OP 的例子:

      <% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
      

      包装条件测试有助于使其更具可读性,因为它在视觉上将测试分开:

      <% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>
      

      当然,通过使用一些明智的空格添加可以使整个示例更具可读性。这是未经测试的,但你会明白的:

      <% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
                                         : question.question 
      %>
      

      或者,写得更惯用:

      <% question = if (question.size > 20)
                      question.question.slice(0, 20) + "..."
                    else 
                      question.question 
                    end
      %>
      

      question.question 也会严重影响可读性,这很容易争论。

      【讨论】:

      • 如果是多行,为什么不直接使用 if...else...end?
      • 因为在 Perl 和 C 领域工作了太多年?我使用任何一种,这取决于情况以及一个在视觉上是否比另一个更清晰。有时 if/else 过于冗长,有时 ?: 很丑陋。
      • @WayneConrad 这个答案中至少解释了一个问题:stackoverflow.com/a/4252945/2597260 比较使用多行 if/三元运算符的几种方法:gist.github.com/nedzadarek/0f9f99755d42bad10c30
      • 你为什么要在true周围加上括号?
      • 因为true 实际上是一个表达式,计算结果为truefalse。最好在视觉上划定界限,因为三元语句会很快变成视觉噪音,降低可读性,从而影响可维护性。
      【解决方案4】:

      一个简单的例子,操作员检查玩家的id是否为1并根据结果设置敌人的id

      player_id=1
      ....
      player_id==1? enemy_id=2 : enemy_id=1
      # => enemy=2
      

      我发现了一个关于该主题的post,这似乎很有帮助。

      【讨论】:

      • 为什么不enemy_id = player_id == 1 ? 2 : 1
      • @AaronBlenkush 感谢您的优雅输入。我还处于菜鸟级别,可能这就是为什么:)
      【解决方案5】:

      它是ternary operator,它的工作方式与 C 中的一样(不需要括号)。这是一个表达方式:

      if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this
      

      但是,在 Ruby 中,if 也是一个表达式,因此:if a then b else c end === a ? b : c,除了优先级问题。两者都是表达式。

      例子:

      puts (if 1 then 2 else 3 end) # => 2
      
      puts 1 ? 2 : 3                # => 2
      
      x = if 1 then 2 else 3 end
      puts x                        # => 2
      

      请注意,在第一种情况下括号是必需的(否则 Ruby 会感到困惑,因为它认为它是 puts if 1 后面有一些额外的垃圾),但在最后一种情况下不需要括号,因为不会出现上述问题。

      您可以使用“long-if”形式来提高多行的可读性:

      question = if question.size > 20 then
        question.slice(0, 20) + "..."
      else 
        question
      end
      

      【讨论】:

      • 放 0 ? 2 : 3 结果也给出 2。这是为什么呢?
      • @X_Trust 在 Ruby 中,唯一的虚假值是 nilfalse。确实不太常见。
      【解决方案6】:

      您使用 ERB 表明您在 Rails 中。如果是这样,那么请考虑 truncate,这是一个可以为您完成这项工作的内置助手:

      <% question = truncate(question, :length=>30) %>
      

      【讨论】:

      • 这太棒了!我到底想做什么!
      • 这已经晚了好几年了,但我对这个答案印象深刻,因为它跳过了所有的句法方面,直奔提问者想要完成的事情。
      • +1,但 erb 不一定意味着 rails(Sinatra、独立 ERB 等)。
      【解决方案7】:
      puts true ? "true" : "false"
      => "true"
      
      
      puts false ? "true" : "false"
      => "false"
      

      【讨论】:

      • 简洁但解释了它的作用。
      • 带括号的小编辑puts (true ? "true" : "false")。否则操作顺序不明确。当我第一次读到这篇文章时,我很困惑,因为我将其读为(puts true) ? "true" : "false",然后期望puts 返回布尔值,该布尔值随后成为字符串值。
      猜你喜欢
      • 2013-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-22
      • 2010-09-28
      相关资源
      最近更新 更多