有人能告诉我为什么很多Ruby布尔方法使用这种双重否定的惯例吗?
!!(boolean expression)
有人能告诉我为什么很多Ruby布尔方法使用这种双重否定的惯例吗?
!!(boolean expression)
双重否定确保无论初始值是什么,您始终会得到true
或false
,而不是一些神秘的值。
这很方便,因为它避免了对您不再需要的对象进行悬空引用,或者需要区分两种假值nil
和false
。
通常您会看到像这样编写的方法:
def logged_in?
!!@session_user
end
这将返回true
或false
的值,该值可以用于所需的任何目的。与此相比:
def logged_in?
@session_user
end
在这种情况下,如果你保存这个值,实际上是在保存整个@session_user
对象,这可能占用相当大的内存空间。这种内存直到你对它的引用超出作用域后才能释放。由于只有一个true
和一个false
,因此不需要进行垃圾回收。class String
def include? regex; self =~ regex end
end
nil
,并在匹配时返回整数。在许多情况下,这并不太重要(nil
类似于false
,而true
可以替代整数)。但是,如果您真的想要布尔值作为返回值,那么可以执行以下操作。class String
def include? regex; !!(self =~ regex) end
end
当匹配时会返回true
,不匹配则返回false
。
在我看来,Ruby 在布尔值方面有点过于聪明了。这是解决聪明导致问题的情况的一种方法。
以下是过度聪明的部分:没有布尔类。相反,有一个约定,任何值都可以作为布尔值。在需要真或假值的上下文中,nil
或 false
表示“false”,而其他任何值表示“true”。true
和 false
的值不是特殊类的一部分,它们是各自类的唯一成员 - 它们存在只是为了使代码更易读。
我想这在大多数情况下都很好用,但是偶尔你需要一个始终为 true
或 false
的布尔值。例如,最近我需要比较两个布尔值,并在它们不同时执行某些特殊操作;唯一的问题是,其中一个是 true
或 false
,而另一个是 1 或 nil
。解决方法?利用 !!nil == false
和 !!1 == true
这个事实。