319

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

例如,这是正确的吗?

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

7 回答 7

511

它是三元运算符,它的工作方式与 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
于 2010-11-23T05:03:55.293 回答
36
puts true ? "true" : "false"
=> "true"


puts false ? "true" : "false"
=> "false"
于 2010-11-23T05:04:38.687 回答
26

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

<% question = truncate(question, :length=>30) %>
于 2010-11-23T16:43:31.280 回答
18

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

(true) ? 1 : 0

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

(true)   \
  ? 1    \
  : 0

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

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

(true) ?
  1 :
  0

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

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


你为什么要在周围加上括号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

于 2010-11-23T06:08:20.090 回答
3

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

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

我发现了一篇关于该主题的帖子,看起来很有帮助。

于 2016-05-29T20:38:50.977 回答
0

最简单的方法:

param_a = 1
param_b = 2

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

因为param_a不等于param_bthenresult的值将是Not same!

于 2019-12-18T09:58:46.757 回答
-1

代码condition ? statement_A : statement_B相当于

if condition == true
  statement_A
else
  statement_B
end
于 2018-09-18T15:13:59.967 回答