在Ruby中=== vs. ==

Mad*_*bæk 68 ruby

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

Case Equality - 对于Object类,实际上与调用#==相同,但通常由后代重写以在case语句中提供有意义的语义.

#==一样的==吗?你能举例说明在case语句中何时/如何使用它?

Jör*_*tag 124

这两者真的无关.特别是,#==是等于运算符,并且#===与平等完全没有关系.就个人而言,我发现#===看起来非常不幸,看起来非常相似#==,使用等号并且通常称为大小写等于运算,三等于运算符三等运算符,它实际上与平等无关.

我打电话#===案件包含操作员(这是我能想到的最好的,我愿意接受建议,特别是来自母语为英语的人).

最好的描述方式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
Run Code Online (Sandbox Code Playgroud)

是相同的

if bar === foo
  baz
end
Run Code Online (Sandbox Code Playgroud)

  • "如果我有一个标有a的抽屉,将b放入其中是否有意义?" 灿烂的形象. (10认同)
  • `Array#===`未定义为ruby 1.8或1.9.1中的成员资格.但是,范围#===`. (4认同)
  • @sepp2k:你说得对。这就是我在不先检查文档的情况下假设合理语义的结果。 (2认同)

sep*_*p2k 10

是的,#==文档的意思是" ==当前对象的实例方法".

=== 用于case语句中:

case obj
when x
  foo
when y
  bar
end
Run Code Online (Sandbox Code Playgroud)

是相同的

if x === obj
  foo
elsif y === obj
  bar
end
Run Code Online (Sandbox Code Playgroud)

一些定义自己的类===是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
Run Code Online (Sandbox Code Playgroud)

是相同的

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
Run Code Online (Sandbox Code Playgroud)


aku*_*uhn 5

有趣的事实,===也用于匹配异常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
Run Code Online (Sandbox Code Playgroud)

这用于匹配系统错误。

SystemCallError.===已定义为当两者具有相同的 errno 时返回 true。使用此系统调用错误编号相同的错误,例如Errno::EAGAINErrno::EWOULDBLOCK,都可以通过仅列出其中之一来挽救。