需要澄清Ruby逻辑运算符

时间:2014-12-09 09:14:41

标签: ruby logical-operators

最近我开始学习Ruby。我在irb练习逻辑运算符,我得到了这些结果,我不明白。你能否为我澄清这些例子?

1 and 0
#=> 0 

0 and 1
#=> 1 

0 && 1
#=> 1 

3 个答案:

答案 0 :(得分:6)

与其他语言(如C)相反,在Ruby中,除nilfalse之外的所有值都被视为“真实”。这意味着,所有这些值在布尔表达式的上下文中都表现得像true

Ruby的布尔运算符将返回truefalse。相反,它们返回导致条件评估完成的第一个操作数(也称为short-circuit evaluation)。对于boolean ,这意味着它将返回第一个“falsy”操作数或最后一个:

false && 1    # => false     (falsy)
nil   && 1    # => nil       (falsy)
false && nil  # => false     (falsy)
1     && 2    # => 2         (truthy)

对于boolean ,这意味着它将返回第一个“truthy”操作数或最后一个:

false || 1    # => 1         (truthy)
nil   || 1    # => 1         (truthy)
false || nil  # => nil       (falsy)
1     || 2    # => 1         (truthy)

这允许一些有趣的结构。使用||设置默认值是一种非常常见的模式,例如:

def hello(name)
  name = name || 'generic humanoid'
  puts "Hello, #{name}!"
end

hello(nil)    # Hello, generic humanoid!
hello('Bob')  # Hello, Bob!

实现同样目标的另一种类似方法是

name || (name = 'generic humanoid')

额外的好处是,如果名称是真实的,则根本不执行任何分配。这种默认值分配甚至有一个快捷方式:

name ||= 'generic humanoid'

如果你小心注意,你会注意到这可能会造成一些麻烦,如果一个有效值是false

destroy_humans = nil
destroy_humans ||= true
destroy_humans
#=> true

destroy_humans = false
destroy_humans ||= true
destroy_humans
#=> true, OMG run!

这很少是预期的效果。因此,如果您知道值只能是Stringnil,那么使用||||=就可以了。如果变量可以是false,则必须更详细:

destroy_humans = nil
destroy_humans = true if destroy_humans.nil?
destroy_humans
#=> true

destroy_humans = false
destroy_humans = true if destroy_humans.nil?
destroy_humans
#=> false, extinction of humanity digressed!

那很接近!但是等等,还有另一个警告 - 特别是使用andor。这些应该 从不 用于布尔表达式,因为它们具有very low operator precedence。这意味着他们将被评估到最后。请考虑以下示例:

is_human = true
is_zombie = false
destroy_human = is_human && is_zombie
destroy_human
#=> false

is_human = true
is_zombie = false
destroy_human = is_human and is_zombie
destroy_human
#=> true, Waaaah but I'm not a zombie!

让我添加一些括号来澄清这里发生的事情:

destroy_human = is_human && is_zombie
# equivalent to
destroy_human = (is_human && is_zombie)

destroy_human = is_human and is_zombie
# equivalent to
(destroy_human = is_human) and is_zombie

所以and和/或者作为“控制流操作符”非常有用,例如:

join_roboparty or fail 'forever alone :('
# this will raise a RuntimeError when join_roboparty returns a falsy value

join_roboparty and puts 'robotz party hard :)'
# this will only output the message if join_roboparty returns a truthy value

我希望澄清您需要了解的有关这些运营商的所有信息。它需要一些习惯,因为它不同于其他语言处理它的方式。但是一旦你知道如何使用不同的选项,你就可以获得一些强大的工具。

答案 1 :(得分:1)

这两个值都是真实的' (在Ruby中,不是nilfalse的所有内容都是真实的),因此在所有情况下都会返回第二个值。相反,如果您使用'或',则会返回第一个值:

1 || 0 #=> 1
0 || 1 #=> 0

答案 2 :(得分:0)

在Ruby中,01都是真值。 (仅nilfalse为假值)

如果两个操作数都是真值,and&&将返回最后一个值。