2009-02-07 47 views

回答

145

不是。它用于将值转换为一个布尔值:

!!nil #=> false 
!!"abc" #=> true 
!!false #=> false 

它通常是没有必要的,因为到Ruby的唯一错误值nilfalse虽则使用,所以它通常最好让该公约的立场。它

觉得作为

!(!some_val) 

一两件事,它的作用是合法的防止数据的一大块被返回。例如,您可能不想在has_image?方法中返回3MB的图像数据,或者您可能不希望返回logged_in?方法中的整个用户对象。使用!!将这些对象转换为简单的true/false

+3

所以这是一个双重否定? – Ross 2009-02-07 22:08:26

+6

这是不错的做法。双重爆炸通常用于谓词(以?结尾的方法)以返回一个明确的布尔值。 – Swanand 2010-03-26 10:12:20

+6

亚历克斯,你不需要担心返回大对象,因为Ruby将返回一个引用,而不是对象的副本。 – DSimon 2012-04-09 22:40:03

28

它返回true如果右边的对象不是nil,而不是falsefalse如果是nilfalse

def logged_in? 
    [email protected]_user 
end 
6

注意,这个成语在其他编程语言中也存在。 C没有固有的bool类型,所以所有的布尔值都被输入为int,代之以01的规范值。注意到本实施例中(加入为了清楚括号内):

!(1234) == 0 
!(0) == 1 
!(!(1234)) == 1 

的“不不”语法任何非零整数转换为1,规范布尔真值。

一般来说,不过,我觉得好多了放在一个合理的比较,而不是使用这个生僻成语:

int x = 1234; 
if (!!x); // wtf mate 
if (x != 0); // obvious 
14

!手段否定布尔状态,二! s是没什么特别的,比其他双重否定。

!true == false 
# => true 

它通常用于强制一个方法返回一个布尔值。它会检测任何种类的真实性,比如字符串,整数和什么不是,并将其变为布尔值。

!"wtf" 
# => false 

!!"wtf" 
# => true 

一个更真实的使用情况:

def title 
    "I return a string." 
end 

def title_exists? 
    !!title 
end 

当你想确保返回一个布尔值,这是非常有用的。恕我直言,这是一种毫无意义,虽然,看到if 'some string'if true是完全相同的流量,但有些人认为显式返回一个布尔值是有用的。

3

如果您需要执行exclusive or,这很有用。从马特范霍恩的答案复制微小的修改:

1^true 
TypeError: can't convert true into Integer 

!!1^!!true 
=> false 

我用它来确保两个变量都是零,或两者都不为零。

raise "Inconsistency" if !!a^!!b 
0

理解它是如何工作的,如果您需要将枚举转换为布尔值,这会非常有用。我有一些代码正是这么做的,使用classy_enum宝石:

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. 

有效的棒棒运营商已经成为了我本来可能写成一个名为to_bool的方法。

3

这是“双重否定”,但这种做法令人沮丧。如果您使用的是rubocop,则会看到它在违反Style/DoubleNegation的情况下投诉此类代码。

rationale状态:

由于这是既神秘的,通常冗余,应该避免 [然后转述:]改变!!something!something.nil?