“==” 最常见的相等性判断
“==” 使用最频繁,它通常用于对象的值相等性(语义相等)判断,在 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 表示对象值相同。
请发表评论