在Ruby中,==和===之间有什么区别? RDoc说:
Case Equality - 对于类Object来说,等同于调用#==,但通常被子类覆盖,以在case语句中提供有意义的语义。
#==
和==
是一样的吗?你能提供一个在case语句中使用它的例子吗?#==
是等于运算符,而#===
与相等毫不相关。个人认为,#===
看起来与#==
非常相似,使用了等号,并经常被称为“case equality操作符”、“triple equals操作符”或“threequals操作符”,但它实际上与相等无关,这让我感到非常遗憾。#===
为“case subsumption操作符”(这是我能想到的最好的术语,如果有更好的建议,尤其是来自以英语为母语的人士,欢迎提出)。a === b
描述为“如果我有一个标记为a
的抽屉,把b
放在里面是否合理?”Module#===
检查是否b.is_a?(a)
。如果您有Integer === 2
,那么将2放入标记为Integer
的盒子中是否合理?是的。那Integer === 'hello'
呢?显然不是。Regexp#===
。它测试与正则表达式匹配。将'hello'
放进标记为/el+/
的盒子中是否合理?是的。Range#===
定义为成员资格测试:如果元素在集合中,则将元素放入标记为集合的盒子中是有意义的。case
表达式有什么关系呢?简单:case foo
when bar
baz
end
与...相同
if bar === foo
baz
end
Array#===
没有定义为成员关系操作符,但是Range#===
有定义。 - sepp2kmyVehicle:Vehicle
和Vehicle<:Object
,我们有myVehicle:Object
(这被称为包容规则)。因此,期望对象的函数将接受车辆”,“在这里,ColorPoint <: Point
,因此任何处理点的程序也将通过包容性接受彩色点。”,“子类型化通过包容性增加了类型的灵活性,但是通过相同的机制可能会导致类型信息的丢失。”还有一条名为“包容性”的类型规则。最著名的Java…是Anchored Exception Declarations论文。 - Jörg W Mittag是的,文档中的#==
指的是“当前对象的实例方法==
”。
===
被用于如下case语句:
case obj
when x
foo
when y
bar
end
与......相同
if x === obj
foo
elsif y === obj
bar
end
一些类定义了它们自己的 ===
方法,例如Range(用于像 include?
一样操作),Class(用于像 obj.is_a?(klass)
一样操作)和 Regexp
(用于像 =~
一样操作,但返回一个布尔值)。而某些没有定义它们自己的 ===
方法,例如数字类和字符串类。
因此,
case x
when 0
puts "Lots"
when Numeric
puts(100.0 / x)
when /^\d+$/
puts(100.0 / x.to_f)
default
raise ArgumentError, "x is not a number or numeric string"
end
是相同的意思
if 0 == x
puts "Lots"
elsif x.is_a? Numeric
puts(100.0 / x)
elsif x =~ /^\d+$/
puts(100.0 / x.to_f)
else
raise ArgumentError, "x is not a number or numeric string"
end
case x; when string --> if "string" == x
? - the12case x; when string
等同于if string === x
,如果string
包含一个字符串,则等同于if string == x
。同样,case x; when "string"
等同于if "string" === x
和if "string" == x
。 - sepp2k有趣的事实是,===
也用于在 rescue
中匹配异常。
这里是一个例子:
class Example
def self.===(exception)
puts "Triple equals has been called."
true
end
end
raise rescue Example
# => prints "Triple equals has been called."
# => no exception raised
这用于匹配系统错误。
SystemCallError.===
已被定义为当两个 errno 相同时返回 true。使用此方法,具有相同错误号的系统调用错误,例如 Errno::EAGAIN
和 Errno::EWOULDBLOCK
,可以通过仅列出其中一个来进行救援。