【发布时间】:2010-10-06 04:42:44
【问题描述】:
只是想知道!! 在 Ruby 中是什么。
【问题讨论】:
标签: ruby
只是想知道!! 在 Ruby 中是什么。
【问题讨论】:
标签: ruby
不是。
用于将值转换为布尔值:
!!nil #=> false
!!"abc" #=> true
!!false #=> false
通常没有必要使用它,因为 Ruby 的唯一错误值是 nil 和 false,所以通常最好保持这种约定。
把它想象成
!(!some_val)
它的合法用途之一是防止返回大量数据。例如,您可能不想在 has_image? 方法中返回 3MB 的图像数据,或者您可能不想在 logged_in? 方法中返回整个用户对象。使用!! 将这些对象转换为简单的true/false。
【讨论】:
.nil? 而不是使用!!?有区别吗?
!!true #=> true 和 true.nil? #=> false
如果右边的对象不是nil而不是false,则返回true,如果是nil或false,则返回false
def logged_in?
!!@current_user
end
【讨论】:
! 表示否定布尔状态,两个!s 没什么特别的,除了一个双重否定。
!true == false
# => true
通常用于强制方法返回布尔值。它将检测任何类型的真实性,例如字符串、整数等,并将其转换为布尔值。
!"wtf"
# => false
!!"wtf"
# => true
更真实的用例:
def title
"I return a string."
end
def title_exists?
!!title
end
当您想确保返回一个布尔值时,这很有用。恕我直言,虽然if 'some string' 和if true 是完全相同的流程,但有些人发现显式返回布尔值很有用。
【讨论】:
title,不如做最接近它的事情......我想
请注意,这个习语也存在于其他编程语言中。 C 没有固有的bool 类型,因此所有布尔值都被键入为int,而规范值为0 或1。以这个例子为例(为清楚起见添加了括号):
!(1234) == 0
!(0) == 1
!(!(1234)) == 1
“not-not”语法将任何非零整数转换为 1,即规范的布尔真值。
不过,总的来说,我发现进行合理的比较比使用这个不常见的习语要好得多:
int x = 1234;
if (!!x); // wtf mate
if (x != 0); // obvious
【讨论】:
如果您需要exclusive or,这很有用。复制 Matt Van Horn 的回答并稍作修改:
1 ^ true
TypeError: can't convert true into Integer
!!1 ^ !!true
=> false
我用它来确保两个变量要么都是 nil,要么都不是 nil。
raise "Inconsistency" if !!a ^ !!b
【讨论】:
如果您需要将枚举转换为布尔值,那么了解它的工作原理会很有用。我有使用classy_enum gem 的代码:
class LinkStatus < ClassyEnum::Base
def !
return true
end
end
class LinkStatus::No < LinkStatus
end
class LinkStatus::Claimed < LinkStatus
def !
return false
end
end
class LinkStatus::Confirmed < LinkStatus
def !
return false
end
end
class LinkStatus::Denied < LinkStatus
end
然后在我的服务代码中,例如:
raise Application::Error unless !!object.link_status # => raises exception for "No" and "Denied" states.
实际上,bangbang 运算符已经变成了我本来可以编写为名为 to_bool 的方法。
【讨论】:
其他答案讨论了!! 的作用以及它是否是好的做法。
但是,没有一个答案给出将值转换为布尔值的“标准 Ruby 方式”。
true & variable
TrueClass,Ruby值true的类,实现了一个方法&,即documented,如下:
如果
obj是nil或false,则返回false,否则返回true。
既然你已经涵盖了标准库,为什么还要使用肮脏的双重否定?
【讨论】: