Answers:
不是这样的。它用于将值转换为布尔值:
!!nil #=> false
!!"abc" #=> true
!!false #=> false
尽管通常不需要使用,因为Ruby的唯一错误值是nil
and false
,因此通常最好保持该约定。
认为是
!(!some_val)
合法使用的一件事是防止返回大量数据。例如,您可能不想在您的has_image?
方法中返回3MB的图像数据,或者您可能不想在logged_in?
方法中返回整个用户对象。使用!!
将这些对象转换为简单的true
/ false
。
.nil?
而不是使用!!
?有区别吗?
!!true #=> true
和true.nil? #=> false
!
表示否定布尔状态,!
除了双重否定外,2 没什么特别的。
!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
,不妨做一些最接近的事情……我想
请注意,该惯用语也存在于其他编程语言中。C没有内在bool
类型,因此所有布尔值都int
以0
或的规范值键入1
。以以下示例为例(为清楚起见添加了括号):
!(1234) == 0
!(0) == 1
!(!(1234)) == 1
“ not-not”语法将任何非零整数转换1
为规范的布尔true值。
但是,总的来说,我发现进行合理的比较比使用这种不常见的习惯要好得多:
int x = 1234;
if (!!x); // wtf mate
if (x != 0); // obvious
这是“双重否定”,但不鼓励这样做。如果您使用的是rubocop,则会看到它在这样的代码上抱怨Style/DoubleNegation
违规。
基本原理指出:
由于这既是隐秘的又通常是多余的,应避免使用[然后解释:]更改
!!something
为!something.nil?
!!false # => false
虽然!false.nil? # => true
!(foo.nil? || foo == false)
-更详细,是,但隐秘性较低。
如果需要将枚举转换为布尔值,则了解其工作原理可能会很有用。我有使用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的方法的东西。