Ruby 中的
&&
和 and
运算符有什么区别?
实际差异在于结合强度,如果您没有做好准备,可能会导致奇怪的行为:
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
。
《Ruby 风格指南》 说得比我更好:
使用&&/||用于布尔表达式和/或控制流。 (规则 拇指:如果你必须使用外括号,那么你就用错了 运营商。)
# boolean expression
if some_condition && some_other_condition
do_something
end
# control flow
document.saved? or document.save!
||
和
&&
与您期望编程语言中布尔运算符的优先级绑定(
&&
非常强,
||
稍弱)。
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 /.
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
。请参阅“
在 Ruby 中使用“and”和“or””了解更多信息。
and 仅检查第一个条件并给出结果 另一方面 && 强烈检查这两个条件并给出逻辑结果。
puts 1 > -1 and 257 < 256
# => false
puts 1 > -1 && 257 < 256
# => true
and
的行为相对于修饰符
if
更可取 - 在第一次尝试中观察
undefined local variable or method 'y'
:
km@latika:~$ irb
irb(main):001:0> x=y if (y="hello")
(irb):1: warning: found `= literal' in conditional, should be ==
(irb):1:in `<main>': undefined local variable or method `y' for main:Object (NameError)
from /usr/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
from /bin/irb:25:in `load'
from /bin/irb:25:in `<main>'
irb(main):002:0> quit
此时,虽然 y
已经被分配,所以我重新启动
irb
以重新开始来证明我的观点:
km@latika:~$ irb
irb(main):001:0> y="hello" and x=y
=> "hello"
irb(main):002:0> quit
在我看来,这是用非 nil (或 false,但这超出了重点)的东西覆盖变量的最好方法。特别是如果我们用 "hello"
代替
complicated_calculation()
。