假设我有类似的东西
true && true #=> true
这是有道理的,所以我尝试类似的东西:
true && "dsfdsf" #=> "dsfdsf"
这让我感到惊讶,因为我经常会做一些事情,比如某事情&&一些东西,我一直认为这是评估为真,并将返回真实.进一步的实验做的事情如下:
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中的布尔运算符是短路的:如果可以从左侧参数确定表达式的值,则不评估右侧参数.
因此,一个简单的心理模型用于评估涉及&& ;;的布尔表达式.是考虑仅涉及两个操作数的第一个表达式:首先计算左侧操作数;如果此操作数的值为nil或false,则返回操作数并且不评估右操作数;如果左侧操作数是其他任何内容,则评估右侧操作符并返回其值.
根据这个定义,很明显,正如您所注意到的,涉及布尔运算符的表达式不返回true或false,而只返回true值或false值.值得注意的是,这在布尔表达式仅用于其真实性或假性的上下文中没有任何区别.
作为左关联的布尔运算符,很容易确定包含多个运算符的表达式的求值顺序,记住&& amp;优先级高于|| (但要小心,并且或者具有相同的优先权).完成此操作后,我们可以很容易地看到表达式的值是最后一个被评估的元素,即允许确定表达式的整体真实性或错误性的元素.
在您的示例(仅由&&运算符组成的表达式)中,只要遇到第一个false值,或者在将最后一个元素作为真值计算之后,就会知道表达式的值.所以,如果前面的所有元素都是真值,则最后一个元素将是最后一个元素,如果遇到任何元素,则它是第一个假值元素.
您可能想知道为什么表达式的值不会转换为true或false;实际上,这种行为可以用在成语中
x = x || default
或者更简短
x ||= default
用于检查x是否为nil,在这种情况下,为其指定一个默认值.