红宝石,!!运算符(a/k/a 双键)[重复]

Posted

技术标签:

【中文标题】红宝石,!!运算符(a/k/a 双键)[重复]【英文标题】:Ruby, !! operator (a/k/a the double-bang) [duplicate] 【发布时间】:2011-04-28 23:39:36 【问题描述】:

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

嗨,

我是 Ruby 新手,找不到任何关于“!!”的描述方法。

这是一个例子:

def signed_in?
  !!current_user
end

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

def signed_in?
  current_user
end

请帮忙。

【问题讨论】:

您是否查看了输入问题标题后给您的问题? 是的,那里什么都没有。我实际上找到了类似的问题来解释我的第二个问题,但我不得不通过“双重爆炸”进行搜索,这并不像您想象的那么明显。 是的,当标题的重要部分是标点符号时,类似的问题算法很容易被欺骗。 见What does !! mean in ruby? 和[什么“!!” Ruby中的符号是什么意思? ](***.com/questions/3821428/…)。 以后尝试使用 symbolhound.com 搜索语法。 【参考方案1】:

在 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。如果不是,它将评估为假。双重否定强制返回值为布尔值。

【讨论】:

so !"" 强制为 true 和 !!"" 为 false 还是空字符串也为 true? !""false,因为唯一的 false-y 值是 falsenil。其他一切都是真实的:phrogz.net/ProgrammingRuby/language.html#truthvalues 我已经编辑了我的答案以使其更清楚。 这是更好的答案,因为它解释了为什么。似乎与您在 Java 中看到的相同类型的 hack 有时通过向其附加“”来将 int 转换为字符串(顺便说一句,我不提倡这样做 - 我相信这在 Java 中是不好的做法)。鉴于这在 Java 中是不好的做法,我不明白为什么像 Ruby 这样的语言会接受它。一切都尽可能使用最少的字符? 实际上几乎不需要双敲。 Ruby 解释器将始终以相同的方式评估表达式的真值,无论是否使用双键。因此,双重敲击只是引入了更多的计算而没有技术收益。 (好处在于安抚 [一些] 人的思想。)实际上 [至少] 有一个地方需要双重打击:当您转换 to_json 时,nil 将转到 null,所以如果如果您希望 JSON 中的值实际上是 truefalse,则需要双击。 所以基本上,!!foo 等价于not (foo == nil or foo == false)【参考方案2】:

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

【参考方案4】:

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

【讨论】:

以上是关于红宝石,!!运算符(a/k/a 双键)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

红宝石连接和联合运算符[重复]

“:foo”在红宝石中是啥意思[重复]

红宝石块? : 表达式 [重复]

红宝石运算符 ||= 智能吗?

红宝石管道操作员

如何使用 DynamoDB 建模双键/二级索引约束?