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

Vit*_*aly 92 ruby operators

可能重复:
什么!! 红宝石意味着什么?

嗨,

我是Ruby的新手,无法找到什么"!!"的描述 手段.

这是一个例子:

def signed_in?
  !!current_user
end
Run Code Online (Sandbox Code Playgroud)

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

def signed_in?
  current_user
end
Run Code Online (Sandbox Code Playgroud)

请帮忙.

pka*_*ing 136

在Ruby(以及许多其他语言)中,有许多值true在布尔上下文中进行求值,而少数值将求值为false.在Ruby中,评估的唯一两件事falsefalse(本身)和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)
Run Code Online (Sandbox Code Playgroud)

在您的示例中,该signed_in?方法应返回一个布尔值(由?字符约定).它用来决定这个值的内部逻辑是检查current_user变量是否设置.如果已设置,它将true在布尔上下文中求值.如果没有,它将评估为假.双重否定强制返回值为布尔值.

  • 这是更好的答案,因为它解释了为什么.看起来像你在Java中看到的相同类型的hack有时会通过在其上附加一个""来将int转换为String(顺便说一句,我不赞成 - 我相信这在Java中是不好的做法).鉴于这在Java中是不好的做法,我不明白为什么像Ruby这样的语言正在接受它.一切尽可能使用最少数量的字符? (2认同)
  • 所以基本上,`!!foo` 等价于 `not (foo == nil or foo == false)` (2认同)

ick*_*fay 114

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


The*_*heo 30

!!只是!(布尔否定运算符)写了两次.它将否定论证,然后否定否定.它很有用,因为您可以使用它从任何值获取布尔值.第一个!将参数转换为布尔值,例如,true如果它是,nil或者false,false否则.让你得到参数的布尔值,第二个将再次否定是falsenil还是false,true只是有关其他的一切.

在Ruby中,您可以在if语句中使用任何值,例如,if current_user如果当前用户不是,则执行nil.大多数情况下这很好,因为它节省了我们键入显式测试(比如if !current_user.nil?,至少六个字符更长).但是,如果在方法暗示它返回一个布尔值时返回一个对象,有时可能会让人感到困惑.名称?以此结尾的方法应返回真值或假值,即它们返回将评估为true或的值false.但是,如果signed_in?返回用户对象,它可能会变得非常混乱.例如,如果你试图调试为什么使用一些代码signed_in?不工作,你可能会得到真糊涂,当用户对象变成了您所预期truefalse.在这种情况下是非常有用的添加!!之前return,因为这保证了truthy或falsy值将用作返回truefalse.