让我说我有类似
的东西true && true #=> true
这是有道理的,所以我尝试了类似的东西:
true && "dsfdsf" #=> "dsfdsf"
这令我感到惊讶,因为我常常会做if something && something
这样的事情,而且我一直认为那是评估为真,并且会回归真实。进一步的实验做的事情如下:
jruby-1.7.3 :009 > "ad" && "dsf"
=> "dsf"
jruby-1.7.3 :010 > "ad" && "sdfd" && nil
=> nil
jruby-1.7.3 :011 > "ad" && nil && "sdf"
=> nil
使Ruby看起来像Ruby返回最后一个值,如果all为true或它找到的第一个false值。为什么这样做?这是一个正确的心理模型吗?
答案 0 :(得分:10)
ruby中的布尔运算符短路:如果可以从左侧参数确定表达式的值,则不评估右侧参数。
因此,用于评估涉及&&
的布尔表达式的简单心智模型是考虑仅涉及两个操作数的第一个表达式:首先计算左侧操作数;如果此操作数的值为nil
或false
,则返回操作数并且不评估右操作数;如果左侧操作数是其他任何内容,则评估右侧操作符并返回其值。
根据这个定义,很明显,正如您所注意到的,涉及布尔运算符的表达式不会返回true
或false
,而只返回 true value 或< em>虚假值。值得注意的是,这在布尔表达式仅用于其 true-ness 或 false-ness 的上下文中没有任何区别。
作为布尔运算符左关联,很容易确定包含多个运算符的表达式的求值顺序,记住&&
的优先级高于||
(但要小心{ {1}}和and
具有相同的优先级。完成此操作后,我们可以很容易地看到表达式的值是最后一个评估元素,即允许确定整体 true-ness 或 false-ness 的元素表达。
在您的示例(仅由or
运算符组成的表达式)中,只要遇到第一个 false值,或者在最后一个元素之后,就会知道表达式的值评估为真值;所以,如果前面的所有元素都是 true valued ,那么评估的最后一个元素将是最后一个元素,如果遇到任何元素,那么它将是第一个 false值元素。
您可能想知道为什么表达式的值未转换为&&
或true
;实际上,这种行为可以用在像
false
或更简短的
x = x || default
用于检查x ||= default
是否为x
,在这种情况下,为其指定默认值。
答案 1 :(得分:1)
是的,它返回最后一个评估值。如果需要,可以转换布尔值:
2.0.0p247 :016 > a = "s"
=> "s"
2.0.0p247 :017 > !!a
=> true
2.0.0p247 :018 > !!("ad" && nil && "sdf")
=> false
但这不是一个好的解决方案。尝试使用布尔类型。