红宝石,!!操作员(a / k / a the double-bang)

时间:2010-10-22 05:05:02

标签: ruby operators

  

可能重复:
  What does !! mean in ruby?

您好,

我是Ruby的新手,无法找到任何描述什么“!!”手段。

以下是一个例子:

def signed_in?
  !!current_user
end

如果这是双重否定,为什么不说:

def signed_in?
  current_user
end

请帮忙。

4 个答案:

答案 0 :(得分:132)

在Ruby(以及许多其他语言)中,有许多值在布尔上下文中评估为true,而少数值将评估为false。在Ruby中,the only two things that evaluate to false are false (itself) and nil

如果你否定了某些东西,那就会强制一个布尔上下文。当然,它也否定了它。如果你对它进行双重否定,它会强制布尔上下文,但会返回正确的布尔值。

例如:

"hello"   #-> this is a string; it is not in a boolean context
!"hello"  #-> this is a string that is forced into a boolean 
          #   context (true), and then negated (false)
!!"hello" #-> this is a string that is forced into a boolean 
          #   context (true), and then negated (false), and then 
          #   negated again (true)
!!nil     #-> this is a false-y value that is forced into a boolean 
          #   context (false), and then negated (true), and then 
          #   negated again (false)

在您的示例中,signed_in?方法应返回一个布尔值(由?字符的约定表示)。用于确定此值的内部逻辑是通过检查是否设置了current_user变量。如果已设置,它将在布尔上下文中计算为true。如果没有,它将评估为假。双重否定强制返回值为布尔值。

答案 1 :(得分:111)

在大多数编程语言中,包括Ruby,!将返回与操作数的布尔值相反的值。因此,当您将两个感叹号链接在一起时,它会将值转换为布尔值。

答案 2 :(得分:29)

!!只是!(布尔否定运算符)写入两次。它将否定论证,然后否定否定。它很有用,因为您可以使用它从任何值获取布尔值。第一个!会将参数转换为布尔值,例如如果是truenil,则为false,否则为false。第二个将再次否定这一点,以便获得参数的布尔值,falsenilfalse的{​​{1}}几乎所有其他内容。

在Ruby中,您可以使用true语句中的任何值,例如如果当前用户不是if,则会执行if current_user。大多数情况下这很好,因为它节省了我们输入显式测试(如nil,至少六个字符)。但是,如果在方法暗示它返回一个布尔值时返回一个对象,有时可能会让人感到困惑。名称以if !current_user.nil?结尾的方法应返回真值或假值,即返回的内容将评估为?true。但是,如果false返回了一个用户对象,它可能会变得非常混乱。例如,如果您尝试调试为什么某些使用signed_in?的代码不起作用,那么当用户对象出现在您期望signed_in?true的位置时,您可能会感到非常困惑。在这种情况下,在false之前添加!!非常有用,因为这样可以确保将真值或假值作为returntrue返回。

答案 3 :(得分:4)

正如您所理解的那样,它是!运算符的双重否定用法。也就是说,虽然它可以是一种检查变量是否可以为零的简写方式,但IMO 太简洁。请查看thisthis帖子。请注意,在Ruby中,测试nil的内容将评估为false。