有人能告诉我为什么很多Ruby布尔方法都使用这种双重否定约定吗?
!!(boolean expression)
答案 0 :(得分:22)
双重否定确保无论初始值如何,您始终会得到true
或false
,而不是一些神秘的价值。
这很方便,因为它可以避免悬挂对您不再需要的对象的引用,或者必须区分两种类型的假值,nil
和false
。
通常你会看到这样编写的方法:
def logged_in?
!!@session_user
end
这将返回true
或false
,该值可用于任何需要的目的。与此相比:
def logged_in?
@session_user
end
在这种情况下,如果保存该值,实际上是在保存整个@session_user
对象,这可能是相当重要的一块内存。在您对它的引用超出范围之前,无法释放此内存。由于只有一个true
和一个false
,因此无需进行垃圾回收。
答案 1 :(得分:3)
假设您要定义一个返回布尔值的方法。例如,字符串是否与正则表达式匹配。
class String
def include? regex; self =~ regex end
end
如果您执行上述操作,它将在不匹配时返回nil
,并在匹配时返回整数。在许多情况下,这并不重要(nil
类似于false
,true
可以替代整数)。但是如果你真的想要一个布尔作为返回值,那么如果你做了
class String
def include? regex; !!(self =~ regex) end
end
匹配时会返回true
,但如果匹配则返回false
。
答案 2 :(得分:1)
在我看来,Ruby对布尔人来说有点太聪明了。这是巧妙导致问题的案例的解决方法。
这是过分的聪明:没有布尔类。相反,有一个约定,其中任何值可以作为布尔值。在需要真或假值的上下文中,nil
或false
表示“假”,其他任何表示“真”。值true
和false
不是特殊类的一部分,它们是各自类的唯一成员 - 它们的存在只是为了使代码更具可读性。
我想这大部分时间都可以正常工作,但是很长一段时间你需要一个布局值总是 true
或false
。例如,我最近需要比较两个布尔值,如果它们不同则做一些特殊的事情;唯一的问题是,其中一个是true
或false
,而另一个是1或nil
。固定?利用!!nil == false
和!!1 == true
。