Ruby 为什么真理与真理&&引用;“字符串”;return";“字符串”;

Ruby 为什么真理与真理&&引用;“字符串”;return";“字符串”;,ruby,truthiness,Ruby,Truthiness,假设我有一个 true && true #=> true 这是有道理的,所以我尝试了以下方法: true && "dsfdsf" #=> "dsfdsf" 这让我很惊讶,因为很多时候我会做一些类似于的事情,如果某件事&&something,我总是认为这是对的,并且会返回真的。进一步的实验包括: jruby-1.7.3 :009 > "ad" && "dsf" => "dsf" jruby-1.7.3 :010 >

假设我有一个

true && true #=> true
这是有道理的,所以我尝试了以下方法:

true && "dsfdsf" #=> "dsfdsf"
这让我很惊讶,因为很多时候我会做一些类似于
的事情,如果某件事&&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看起来要么返回最后一个值(如果全部为真),要么返回它找到的第一个假值。为什么会这样?这是一个正确的心智模型吗?

是的,它返回上一次评估的值。如果需要,可以转换布尔值:

2.0.0p247 :016 > a = "s"
 => "s" 
2.0.0p247 :017 > !!a
 => true 
2.0.0p247 :018 > !!("ad" && nil && "sdf")
 => false

但这不是一个好的解决方案。尝试改用布尔类型。

ruby中的布尔运算符存在短路:如果可以从左侧参数确定表达式的值,则不会计算右侧参数

因此,一个更简单的用于评价布尔表达式的心理模型,涉及到>和是考虑只涉及两个操作数的第一个表达式:首先对左手操作数进行评估;如果此操作数的值为

nil
false
,则返回该操作数,而不计算右侧操作数;如果左侧操作数是其他操作数,则计算右侧运算符并返回其值

从这个定义可以清楚地看出,正如您所注意到的,涉及布尔运算符的表达式不会返回
true
false
,而只是返回一个真值或假值。值得注意的是,在布尔表达式仅用于其真值或假值的上下文中,这并没有任何区别

作为左关联的布尔运算符,很容易确定包含多个运算符的表达式的求值顺序,记住
&&
的优先级高于
|
(但是要注意
具有相同的优先级)。完成此操作后,我们可以很容易地看到表达式的值是最后计算的元素,即允许确定表达式整体真实性或虚假性的元素

在您的示例中(仅由
&&
运算符组成的表达式),一旦遇到第一个假值,或在最后一个元素被计算为真值后,表达式的值即为已知值;因此,如果前面的所有元素都是真值的,则最后一个被计算的元素将是最后一个元素,如果遇到任何元素,则将是第一个假值元素

您可能想知道为什么表达式的值没有转换为
true
false
;实际上,这种行为可以用在像这样的成语中

x = x || default
还是更简短

x ||= default

用于检查
x
是否为
nil
,在这种情况下,为其指定一个默认值。

读取它的逻辑相同行为。价值观本身就是真实的或虚假的。为什么逻辑运算符不应该直接返回它们而不是返回一个单独的布尔类型?这并不能回答为什么返回字符串而不是布尔类型的问题。他可能已经知道如何转换为布尔值。只有第一句是答案。不,第一句也不是答案。问题是为什么。有趣的是,
x | | |=default
的行为与
x=x | | | default
不同,尽管与问题没有直接关系,因为如果
x
不是
nil
false
,则不会执行赋值。然而,我觉得在介绍后者时不引用另一个(更常见的)成语是不对的。此外,我相信这种行为在第一位实际上是可能的,因为它在第一位与扩展形式一致,除了可能的赋值。