问题描述
在PHP中,其计算结果为true
:
In PHP, this evaluates to true
:
$a = 1
$b = 2
var_dump($a && $b); // true
在红宝石中,其计算结果为2
:
In ruby, this evaluates to 2
:
a = 1
b = 2
p a && b # 2
为什么ruby不返回最后一个语句的值(当第一个为true且第二个也为true时)并且不返回布尔值?
Why does ruby return the value of the last statement (when the first is true and the second one is also true) and does not return a boolean?
我有两个数组,并使用一个外部迭代器对其进行迭代:
I have two arrays and I iterate them with an external iterator:
a = [1,2,3].to_enum
b = [5,6,7].to_enum
c = []
begin
while a_next = a.next && b_next = b.next
result = a_next + b_next
p "a[x] + b[x] = c[x] = #{a_next} + #{b_next} = #{result}"
c << result
end
rescue
p c
end
条件:while a_next = a.next && b_next = b.next
设置a_next = b_next
(我认为第一个问题似乎与此行为有关).但是,当我包装两个&&
操作数时,它可以按预期工作:(a_next = a.next) && (b_next = b.next)
.
The condition: while a_next = a.next && b_next = b.next
sets a_next = b_next
(the first question seems related to this behavior, I think).But when I wrap the two &&
operands, it works as expected: (a_next = a.next) && (b_next = b.next)
.
推荐答案
这里有几个方面.
因为这样更有用.实际上,这种语义非常有用,以至于PHP 7对其进行了添加(但作为新的运算符??
).在Ruby中,就像在PHP中一样,所有值都是真实的或虚假的.与PHP不同,Ruby对它有一个更为严格的概念:只有false
和nil
是虚假的,其他所有东西都是真实的.这使您可以轻松地设置默认值:
Because it is more useful this way. This semantics is in fact so useful that PHP 7 added it (but as a new operator, ??
). In Ruby, just as in PHP, all values are truthy or falsy. Unlike PHP, Ruby has a much stricter idea about it: only false
and nil
are falsy, everything else is truthy. This allows you to easily give defaults:
name = options[:name] || "John Doe"
如果未找到options[:name]
并返回nil
,则该部分是虚假的,并且将返回||
的右侧;否则,返回||
.否则,将返回options[:name]
.
If options[:name]
is not found and returns nil
, then that part is falsy and the right side of ||
will be returned; otherwise, options[:name]
will be returned.
在大多数情况下,您不需要 布尔值,因为真实性或虚假性就足够了.例如,如果您真的想拥有一个布尔值,以便不将私有信息泄漏到类之外,则习惯用法!!value
很常见:
In most cases you don't need a boolean, because truthiness or falsiness suffices. If you really really want to have a boolean, for example in order not to leak private information out of a class, the idiom !!value
is common:
def has_name?
!!(self.name || self.nickname)
end
!
(否定)的结果始终为布尔值;如果您两次否定,则会将真实性转换为true
,将虚假度转换为false
.
The result of !
(negation) is always boolean; if you negate twice, you will convert truthiness to true
and falsiness to false
.
最后,
然后,您需要将它们包装起来.这是由于运算符的优先级,并且在设计上像这样工作,因为写起来更正常
Then you need to wrap them. That's due to operator precedence, and works like this by design, because it is more normal to write
blue_green = colour == :blue || colour == :green
比
blue_green = (colour == :blue || colour == :green)
实际上还有另一组布尔运算符设计为可以像您建议的那样工作,唯一的区别是优先级,因此您可以编写并使其起作用:
There is another set of boolean operators that are actually designed to work like you propose, the only difference being the precedence, so you could write this and have it work:
while a_next = a.next and b_next = b.next
与
while (a_next = a.next) && (b_next = b.next)
一个警告:错误地使用and
和or
运算符而不是&&
和||
是一个常见的错误,许多样式指南完全禁止使用它们(它们仅对有用在这种情况下-循环条件内的赋值-可以用括号来解决). 例如:
A warning though: using and
and or
operators instead of &&
and ||
improperly is a common enough mistake that many style guides outright ban them (they are useful only in this context - assignment inside loop conditions - and it can be solved with parentheses instead). E.g.:
这篇关于Ruby的&&操作员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!