什么!!红宝石意味着什么?

时间:2009-02-07 21:53:47

标签: ruby

只是想知道Ruby中的!!是什么。

8 个答案:

答案 0 :(得分:154)

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

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

通常没有必要使用,因为Ruby的唯一错误值是nilfalse,所以通常最好让这个约定成立。

将其视为

!(!some_val)

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

答案 1 :(得分:29)

如果右侧的对象不是true而不是nilfalse,如果它是falsenil,则返回false

def logged_in?   
  !!@current_user
end

答案 2 :(得分: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 :(得分:6)

请注意,这个习语也存在于其他编程语言中。 C没有固有bool类型,因此所有布尔值都被输入为int,而标准值为01。采用这个例子(为了清楚起见,添加了括号):

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

“not-not”语法将任何非零整数转换为1,即规范布尔值。

但总的来说,我发现进行合理的比较比使用这种不常见的习语要好得多:

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

答案 4 :(得分:3)

如果你需要exclusive or,这很有用。复制Matt Van Horn的答案略有修改:

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

!!1 ^ !!true
=> false

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

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

答案 5 :(得分:3)

这是"双阴",但这种做法令人沮丧。如果您正在使用rubocop,那么您会发现此类代码因Style/DoubleNegation违规行为而抱怨。

rationale州:

  

由于这既是神秘的,也是多余的,应该避免   [然后解释:]将!!something更改为!something.nil?

答案 6 :(得分:0)

如果需要将枚举转换为布尔值,了解它的工作原理会非常有用。我使用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的方法。

答案 7 :(得分:0)

其他答案讨论了!!的作用以及它是否是一种好的做法。

但是,所有答案都没有给出将值转换为布尔值的“标准Ruby方法”。

true & variable

TrueClass是Ruby值true的类,它实现了一种方法&,它是documented,如下所示:

如果falseobjnil,则返回false,否则返回true

当您覆盖标准库时,为什么要使用肮脏的双重否定法?