有时我会看到这样的 Ruby 代码
def sent?
!!@sent_at
end
这似乎不合逻辑。有必要在这里使用 double!
吗?就我而言,这可能只是
def sent?
@sent_at
end
更新:那么这些之间有什么区别
def sent?
!!@sent_at
end
def sent?
@sent_at.nil?
end
def sent?
@sent_at == nil
end
有时我会看到这样的 Ruby 代码
def sent?
!!@sent_at
end
这似乎不合逻辑。有必要在这里使用 double!
吗?就我而言,这可能只是
def sent?
@sent_at
end
更新:那么这些之间有什么区别
def sent?
!!@sent_at
end
def sent?
@sent_at.nil?
end
def sent?
@sent_at == nil
end
我不是 Ruby 人,但我想这是为了将 @sent_at 转换为布尔值。
更新:啊哈,我看到了你的更新。注意false
和nil
是不同的;false.nil? == false
, 而nil.nil? == true
. 仅在 ruby 中false
,nil
将被视为“假”;甚至一个空字符串 ,''
也被评估为true
(它False
在 python 中)。
Double Bang
用于在 Ruby 中将任何内容转换为布尔值。
http://rubyquicktips.com/post/583755021/convert-anything-to-boolean
它强制一个真值为真,一个假值为假。在 Ruby 中,唯一的假值是 nil 和 false,其他所有值都是真值。
!falsyExpr # given -> true
!true # and -> false
!!falsyExpr # then -> true -> false
!truthyExpr # given -> false
!false # and -> true
!!truthyExpr # then -> false -> true
当从这样的方法返回时,使用!!expr
over的原因是表单只会产生 true 或 false。这避免了泄漏细节,避免了意外的强引用,减少了调试时的混淆,防止了 false/nil 混淆的情况等。它也比具有相同语义的 更短。expr
!!expr
expr ? true : false
当评估为 nil时,表单expr == nil
和expr.nil?
仅评估为 trueexpr
。expr
如果评估为任何其他值,包括 false ,它们都是false 。这将它们与对于false 和 nil值!expr
都评估为 true 的区别。
当然,以上所有都是预期的行为。由于 Ruby 的开放性和运算符重载,有可能(并且非常错误地)创建改变这种预期行为的新方法(除非一些实现优化怪癖)。
使用!!
确保返回true
或false
返回。所以,是的,这是有道理的。
@sent_at = 'Foo'
!!@sent_at # => true
@sent_at = nil
!!@sent_at # => false
它将非布尔类型转换为布尔(true
或false
)。
这是执行此操作的快捷方式,而不是尝试显式转换(可能需要更多字符)。这 !运算符否定其参数的真实性。因此,使用了其中的两个。
另请参阅perl(或大多数其他语言)的双重否定 (!!) 的使用。