Ruby 中的 &&
和 and
运算符有什么区别?
and
与 &&
相同,但带有 lower precedence。他们都使用 short-circuit evaluation。
警告:and
的优先级甚至低于 =
,因此您通常希望避免使用 and
。应该使用 and
的示例可以在 Rails 指南中的“Avoiding Double Render Errors”下找到。
实际的区别是结合强度,如果你没有准备好,它可能会导致特殊的行为:
foo = :foo
bar = nil
a = foo and bar
# => nil
a
# => :foo
a = foo && bar
# => nil
a
# => nil
a = (foo and bar)
# => nil
a
# => nil
(a = foo) && bar
# => nil
a
# => :foo
||
和 or
同样适用。
a = foo and bar
and (a = foo ) && bar
证明 and
的优先级低于 &&
。
a = foo and bar
等同于 (a = :foo) and nil
。由于赋值返回一个逻辑真值 (:foo
),因此第二部分计算失败,返回 nil
。
Ruby Style Guide 说得比我好:
使用 &&/||用于布尔表达式和/或控制流。 (经验法则:如果您必须使用外括号,则说明您使用了错误的运算符。)
# boolean expression
if some_condition && some_other_condition
do_something
end
# control flow
document.saved? or document.save!
and
/or
,他们可能有一点。通常它们在控制流 could be more obviously written with if
/unless
operators 中的使用(例如 document.save! unless document.saved?
)
||
和 &&
与编程语言中布尔运算符的优先级绑定(&&
非常强,||
稍弱)。
and
和 or
的优先级较低。
例如,与 ||
不同,or
的优先级低于 =
:
> a = false || true
=> true
> a
=> true
> a = false or true
=> true
> a
=> false
同样,与 &&
不同,and
的优先级也低于 =
:
> a = true && false
=> false
> a
=> false
> a = true and false
=> false
> a
=> true
此外,与 &&
和 ||
不同的是,and
和 or
以相同的优先级绑定:
> !puts(1) || !puts(2) && !puts(3)
1
=> true
> !puts(1) or !puts(2) and !puts(3)
1
3
=> true
> !puts(1) or (!puts(2) and !puts(3))
1
=> true
弱绑定 and
和 or
可能对控制流有用:参见 http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/ 。
||
不同,or
的优先级低于 =
” ...现在更有意义了,谢谢!
and
的优先级低于 &&
。
但是对于一个不起眼的用户,如果它与其他优先级介于两者之间的运算符一起使用,例如赋值运算符,则可能会出现问题:
def happy?() true; end
def know_it?() true; end
todo = happy? && know_it? ? "Clap your hands" : "Do Nothing"
todo
# => "Clap your hands"
todo = happy? and know_it? ? "Clap your hands" : "Do Nothing"
todo
# => true
and
的优先级较低,通常我们将其用作控制流修饰符,例如 if
:
next if widget = widgets.pop
变成
widget = widgets.pop and next
对于 or
:
raise "Not ready!" unless ready_to_rock?
变成
ready_to_rock? or raise "Not ready!"
我更喜欢使用 if
而不是 and
,因为 if
更容易理解,所以我忽略了 and
和 or
。
有关详细信息,请参阅“Using “and” and “or” in Ruby”。
我不知道这是 Ruby 的意图还是这是一个错误,但请尝试下面的代码。此代码在 Ruby 版本 2.5.1 上运行,并且在 Linux 系统上。
puts 1 > -1 and 257 < 256
# => false
puts 1 > -1 && 257 < 256
# => true
并且只检查第一个条件并给出结果 && 强烈地检查两个条件并给出逻辑结果。
&&
,而and
应仅用于非常特殊的情况。and
的另一种思考方式是反向的if
语句修饰符:next if widget = widgets.pop
变为widget = widgets.pop and next
。这是一种很好的表达方式,真的让它在我脑海中“点击”。 (并且or
就像一个反转的unless
修饰符。)