红宝石,!!运算符(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 值是 false
和 nil
。其他一切都是真实的:phrogz.net/ProgrammingRuby/language.html#truthvalues 我已经编辑了我的答案以使其更清楚。
这是更好的答案,因为它解释了为什么。似乎与您在 Java 中看到的相同类型的 hack 有时通过向其附加“”来将 int 转换为字符串(顺便说一句,我不提倡这样做 - 我相信这在 Java 中是不好的做法)。鉴于这在 Java 中是不好的做法,我不明白为什么像 Ruby 这样的语言会接受它。一切都尽可能使用最少的字符?
实际上几乎不需要双敲。 Ruby 解释器将始终以相同的方式评估表达式的真值,无论是否使用双键。因此,双重敲击只是引入了更多的计算而没有技术收益。 (好处在于安抚 [一些] 人的思想。)实际上 [至少] 有一个地方需要双重打击:当您转换 to_json
时,nil
将转到 null
,所以如果如果您希望 JSON 中的值实际上是 true
或 false
,则需要双击。
所以基本上,!!foo
等价于not (foo == nil or foo == false)
【参考方案2】:
在包括 Ruby 在内的大多数编程语言中,!
将返回与操作数的布尔值相反的值。因此,当您将两个感叹号链接在一起时,它会将值转换为布尔值。
【讨论】:
【参考方案3】:!!
只是!
(布尔否定运算符)写了两次。它将否定论点,然后否定否定。它很有用,因为您可以使用它从任何值中获取布尔值。第一个 !
会将参数转换为布尔值,例如true
如果是 nil
或 false
,否则 false
。第二个将再次否定它,以便您获得参数的布尔值,false
用于 nil
或 false
,true
用于几乎所有其他内容。
在 Ruby 中,您可以在 if
语句中使用任何值,例如如果当前用户不是nil
,if current_user
将执行。大多数情况下,这很好,因为它节省了我们输入显式测试的时间(比如if !current_user.nil?
,它至少长了六个字符)。但有时,当方法暗示它返回一个布尔值时,如果你返回一个对象,这可能真的很令人困惑。名称以?
结尾的方法应该返回真值或假值,即它们返回的值将评估为true
或false
。但是,如果signed_in?
返回一个用户对象,它会变得非常混乱。例如,如果您尝试调试为什么使用signed_in?
的某些代码不起作用,当用户对象出现在您期望的true
或false
的位置时,您可能会感到非常困惑。在这种情况下,在return
之前添加!!
很有用,因为这可以保证真值或假值将以true
或false
返回。
【讨论】:
【参考方案4】:正如您正确理解的那样,这是!
运算符的双重否定用法。也就是说,虽然它可以是一种检查变量是否可以为 nil 的简写方式,但 IMO 太简洁了。看看this 和this 的帖子。请注意,在 Ruby 中,将某些内容测试为 nil 将评估为 false。
【讨论】:
以上是关于红宝石,!!运算符(a/k/a 双键)[重复]的主要内容,如果未能解决你的问题,请参考以下文章