最近我开始学习Ruby。我在irb
练习逻辑运算符,我得到了这些结果,我不明白。你能否为我澄清这些例子?
1 and 0
#=> 0
0 and 1
#=> 1
0 && 1
#=> 1
答案 0 :(得分:6)
与其他语言(如C)相反,在Ruby中,除nil
和false
之外的所有值都被视为“真实”。这意味着,所有这些值在布尔表达式的上下文中都表现得像true
。
Ruby的布尔运算符将不返回true
或false
。相反,它们返回导致条件评估完成的第一个操作数(也称为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!
这很少是预期的效果。因此,如果您知道值只能是String
或nil
,那么使用||
和||=
就可以了。如果变量可以是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!
那很接近!但是等等,还有另一个警告 - 特别是使用and
和or
。这些应该 从不 用于布尔表达式,因为它们具有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中,不是nil
或false
的所有内容都是真实的),因此在所有情况下都会返回第二个值。相反,如果您使用'或',则会返回第一个值:
1 || 0 #=> 1
0 || 1 #=> 0
答案 2 :(得分:0)
在Ruby中,0
和1
都是真值。 (仅nil
和false
为假值)
如果两个操作数都是真值,and
,&&
将返回最后一个值。