ruby 比较符号==, ===, eql?, equal?

“==” 最常见的相等性判断

  “==” 使用最频繁,它通常用于对象的值相等性(语义相等)判断,在 Object 的方法定义中,“==” 比较两个对象的 object_id 是否一致,通常子类都会重写覆盖这个方法,通过比较内部值来判断对象是否相等。

  比如 String 类,他是来计较实际的文字串是否相同,而不在意是否来自同一个内存区域

a = 'abc'       #=> 44547600
b = 'abc' + ''  #=> 44547540
a == b    #=> true

“===” 主要用于 case 语句的相容判断

  通常情况下这中方式与==是一样的,但是在某些特定情况下,===有特殊的含义:

  • 在Range中===用于判断等号右边的对象是否包含于等号左边的Range;
  • 正则表达式中用于判断一个字符串是否匹配模式,
  • Class定义===来判断一个对象是否为类的实例,
  • Symbol定义===来判断等号两边的符号对象是否相同
(1..10) === 5 #=> true: 5属于range 1..10
/d+/ === '123'  #=> true: 字符串匹配这个模式
String === 's'   #=> true: "s" 是一个字符串类的实例
:s === 's'    #=> false
case some_object
when /a regex/
  # The regex matches
when 2..4
  # some_object is in the range 2..4
when lambda {|x| some_crazy_custom_predicate }
  # the lambda returned true
end

#等同于

if /a regex/ === some_object
  # The regex matches
elsif (2..4) === some_object
  # some_object is in the range 2..4
elsif lambda {|x| some_crazy_custom_predicate } === some_object
  # the lambda returned true
end

“eql?” 对象 hash 值判断

  eql? 用于对象 hash 值判断,如果两个对象的 hash 值相等,就返回 true,否则返回 false。Object 的定义里,“eql?” 和 “==” 是等价的。通常可以把 “eql?” 看作比 “==” 更严格的相等,比如:

1 == 1.0     #=> true
1.eql? 1.0   #=> false

str1 = 'a'
str2 = 'a'
puts str1 == str2 #=> true

str1.hash #=> 104582539
str2.hash #=> 104582539
puts str1.eql? str2 #=> hash值相等 true

str1.object_id #=> 20804940
str2.object_id #=> 20804920
puts str1.equal? str2 #=> object_id不相等 false
 

“equal?” 相同对象判断

  “equal?” 其实是最简单的,但是也是最容易让人搞混的判断。说它简单是因为这个方法的语义是比较两个对象是否相同(是否有相同的 object_id),Object 的方法适用所有对象,不应该对其重写覆盖。说它容易让人搞混,是因为 ruby 和 java 中 “==” 和 “equal?” 方法的语义正好是相反的,ruby 中 “equal?” 表示对象引用相同,而 java 表示对象值相同。

原文地址:https://www.cnblogs.com/wf0117/p/9022603.html