想知道 Ruby 中的 !!
是什么。
不是不是。
它用于将一个值转换为布尔值:
!!nil #=> false
!!"abc" #=> true
!!false #=> false
通常情况下不必使用 though
,因为在 Ruby 中唯一的假值是 nil
和 false
,所以最好让这个约定保持不变。
可以把它看作是
!(!some_val)
它合法使用的一个方面是防止返回大量的数据。例如,您可能不想在has_image?
方法中返回3MB的图像数据,或者您可能不想在logged_in?
方法中返回整个用户对象。使用!!
将这些对象转换为简单的true
/false
。
如果右侧的对象不是nil
和false
,则返回true
;如果右侧的对象是nil
或false
,则返回false
def logged_in?
!!@current_user
end
!
代表取反布尔值状态,两个!
没有什么特殊的意义,除了表示双重否定。
!
表示对一个布尔值进行取反操作,即将true
变为false
,将false
变为true
。两个!
并不会有其他特殊的含义,仅仅表示双重否定,即将一个布尔值取反两次,得到与原始值相同的结果。
!true == false
# => true
这通常用于强制一个方法返回布尔值。它会检测任何类型的真实性,比如字符串、整数等等,并将其转换为布尔值。
!"wtf"
# => false
!!"wtf"
# => true
一个更真实的用例:
def title
"I return a string."
end
def title_exists?
!!title
end
在确保返回布尔值时,这很有用。尽管我认为这有点毫无意义,因为if 'some string'
和if true
的流程是完全相同的,但有些人发现显式返回布尔值很有用。
title
,那么最好做最接近的事情...我想。 - Carson Myersbool
类型,因此所有布尔值都被定义为int
类型,并具有规范值0
或1
。以这个例子为例(为了清晰起见添加了括号):!(1234) == 0
!(0) == 1
!(!(1234)) == 1
“非非”语法将任何非零整数转换为1
,即规范的布尔值真。
总的来说,我发现使用合理的比较要比使用这种不常用的习惯语法更好:
int x = 1234;
if (!!x); // wtf mate
if (x != 0); // obvious
!!false # => false
而
!false.nil? # => true
- Doug!(foo.nil? || foo == false)
——更冗长,是的,但更少含糊。 - David Moles如果你需要进行异或操作,这将非常有用。以下是稍作修改的Matt Van Horn的答案:
1 ^ true
TypeError: can't convert true into Integer
!!1 ^ !!true
=> false
我用它来确保两个变量要么都是nil,要么都不是nil。
raise "Inconsistency" if !!a ^ !!b
如果你需要将枚举转换为布尔值,了解它的工作原理可能会很有用。我有一段代码可以使用 classy_enum
gem 来实现这一点:
class LinkStatus < ClassyEnum::Base
def !
return true
end
end
class LinkStatus::No < LinkStatus
end
class LinkStatus::Claimed < LinkStatus
def !
return false
end
end
class LinkStatus::Confirmed < LinkStatus
def !
return false
end
end
class LinkStatus::Denied < LinkStatus
end
然后在服务代码中,我有如下示例:
raise Application::Error unless !!object.link_status # => raises exception for "No" and "Denied" states.
实际上,bangbang 运算符已经成为我本来可能写成名为 to_bool 的方法。
!!
的作用以及它是否是一种好的编程实践。true & variable
TrueClass
,Ruby值true
的类,实现了一个方法&
,文档如下:
如果
obj
是nil
或false
,则返回false
,否则返回true
。
当标准库已经为你提供了支持时,为什么要使用不洁的双重否定呢?
.nil?
而不是使用!!
?这两者有区别吗? - ashes999!!true #=> true
和true.nil? #=> false
。 - Alex Wayne