【发布时间】:2011-04-26 21:47:08
【问题描述】:
谁能告诉我为什么很多 Ruby 布尔方法都使用这种双重否定约定?
!!(boolean expression)
【问题讨论】:
-
不是 rubyist,但我想将值强制为布尔值?
标签: ruby
谁能告诉我为什么很多 Ruby 布尔方法都使用这种双重否定约定?
!!(boolean expression)
【问题讨论】:
标签: ruby
双重否定确保无论初始值如何,您总是会得到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 在布尔运算方面有点太聪明了。这是聪明导致问题的解决方法。
这就是过度的聪明之处:没有布尔类。相反,有一个约定 any 值可以用作布尔值。在需要真或假值的上下文中,nil 或 false 表示“假”,其他任何内容都表示“真”。 true 和 false 值不是特殊类的一部分,它们是各自类的唯一成员——它们的存在只是为了使代码更具可读性。
我想这在大多数情况下都可以正常工作,但每隔很长一段时间你就需要一个 总是 true 或 false 的布尔值。例如,我最近需要比较两个布尔值并在它们不同时做一些特别的事情;唯一的问题是,其中一个是true 或false,而另一个是1 或nil。使固定?利用!!nil == false 和!!1 == true 的事实。
【讨论】: