我注意到Ruby中的If Statements中有点奇怪(我认为)。这是一个例子:
my_number = nil
if my_number < 3
'number is less than 3'
end
显然,当您运行此代码时,您将获得“Fixnum与nil失败的比较”错误。现在这里有点奇怪。如果我在If语句中进行一点改动以检查nil,它可以正常工作。例如:
my_number = nil
if my_number && my_number < 3
'number is less than 3'
end
添加nil检查使其不会崩溃。这听起来可能都很愚蠢,但我无法弄清楚为什么会有效。它不应该仍然会出错吗?
感谢任何能够解释这一点的人。 :)谢谢!
答案 0 :(得分:4)
布尔表达式以所谓的“短路”方式进行评估。也就是说,只要它知道结果,它就不会继续尝试评估表达式。
所以if my_number
和false
一样,所以没有必要继续,因为false && <anything>
总是假的。
这是一个有用的语言功能,许多语言都是这样工作的(原始的Visual Basic是我能想到的一个例外),因为它可以让你完成这种测试而不需要繁琐的嵌套'if'。
答案 1 :(得分:1)
这不是特定于Ruby的方式:我已经注意到了我曾经使用的所有语言中的这种行为,从Pascal到Java。
如果你有布尔表达式b1 && b2 && b3 ... && bn
,大多数语言保证从左到右评估bi
,如果某些bi
结果是false
,评估将会停下来(因为整个表达式都是假的)。与布尔||
运算符相同。
答案 2 :(得分:0)
测试nil必须可以,所以if nil
或类似的东西几乎适用于所有语言。
但是对于算术比较,如果它没有抛出异常,则必须返回true或false。无论哪种方式都存在问题。
真实的没有意义,因为nil将是&lt;和&gt;比3。
虚假几乎一样糟糕,因为现在nil < 3
和nil >= 3
都是假的,这并不理想。
因此,比较方法会抛出异常。问题解决了。
答案 3 :(得分:0)
nil是“falsy”。在irb中试试这个:
irb(main):001:0> puts "Nil is true " if nil
=> nil
irb(main):002:0> puts "Nil is not true " if !nil
Nil is not true
=> nil
nil与false不同,但是它在循环和其他测试中对它有很大的帮助:
false == nil
=> false
因为你的第一部分和假红宝石做了懒惰的事情,甚至懒得评估下一个比特,如果它是&gt; 3。
答案 4 :(得分:0)
正在发生的事情称为短路评估。你的陈述可以这样想:
if( my_number )
if( my_number < 3)
'number is less than 3'
end
end
由于第一个条件为假,因此没有理由评估该语句的第二个条件 - my_number&lt; 3部分。