=== vs。==在Ruby中


70

在Ruby中,==和===有什么区别?该RDoc的

大小写相等-对于类Object,实际上与调用#==相同,但通常被后代覆盖以在case语句中提供有意义的语义。

#==一样的==吗?您能否提供一个在case语句中何时/如何使用它的示例?


我认为这是最好的答案stackoverflow.com/a/4467823/5048945
mmike

Answers:


128

两者之间确实没有任何关系。特别#==是,等于运算符,#===与相等绝对无关。就我个人而言,我觉得很不幸,它#===看起来与#==,使用等号并在与等式无关的情况下通常称为大小写相等运算符三等号运算threequals运算符

我打电话#===情况下,包容操作(这是我能想出的最好,我很开放的建议,特别是从以英语为母语)。

最好的描述方式a === b是“如果我有一个标有抽屉的抽屉a,放入抽屉是否有意义b?”

因此,例如,Module#===测试是否b.is_a?(a)。如果有的话Integer === 22在贴有标签的盒子里有意义Integer吗?是的,它确实。那Integer === 'hello'呢 显然不是。

另一个例子是Regexp#===。它测试是否匹配。放入'hello'标有标签的盒子有意义/el+/吗?是的,它确实。

对于范围等集合,Range#===定义为成员资格测试:将元素放入标有集合的框中是有意义的(如果该元素在集合中)。

就是#===这样:它测试参数是否可以包含在接收方之下。

这是什么必须与case表情?简单:

case foo
when bar
  baz
end

是相同的

if bar === foo
  baz
end

4
Array#===未定义为ruby 1.8或1.9.1的成员资格。Range#===是的。
sepp2k 2010年

1
@ sepp2k:你是对的。这就是我假设明智的语义而不先检查文档的结果。
约尔格W¯¯米塔格

10
“如果我有一个标有a的抽屉,在里面放b是否有意义?”。出色的图像。
tokland 2010年

1
这个运算符的词源是什么?是在Perl或CLU中使用了它,还是Matz制作了新的东西?
安德鲁·格林

1
@BKSpurgeon:真的吗?我什至不是母语人士,而且我知道这个词。而且我认为它很常用。特别是在编程中。例如,在著名的Jigsaw论文中:“基于Mixin的继承包含了基于LISP的面向对象语言的典型形式的线性多重继承的其他形式”,而在同一篇论文中,“就像模块和接口包含了链接器支持的某些功能一样,继承也包含了Linkers支持的某些功能。文字编辑器”。
约尔格W¯¯米塔格

11

是的,#==文档中的意思是“==当前对象的实例方法”。

=== 用于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=~除了返回布尔值以外,作用类似于)。一些没有定义自己===的类是数字类和String。

所以

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

好奇是否要在when语句中输入字符串,这类似于说case x; when string --> if "string" == x吗?
the12

1
@ the12您是在问Ruby是否会自动在标识符周围添加引号,或者是拼写错误?无论如何case x; when string都等于if string === x,如果string包含字符串,则等于if string == x。同样case x; when "string"等同于if "string" === xif "string" == x
sepp2k

4

有趣的是,===还用于匹配异常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::EAGAINErrno::EWOULDBLOCK

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.