在Ruby中,我们可以使用Object#equal?方法去判断两个对象是否完全相同,同时Ruby还有一个叫Object#eql?的方法,它用来判断两个对象是否含有相同的值。
str1 = "Sample string"
str2 = str1.dup
str1.eql?(str2) #=> true
str1.equal?(str2) #=> false
通过object_id可以清楚的看出str1与str2是两个不同的对象。
str1.object_id #=> 70334175057920
str2.object_id #=> 70334195702480
Set对象中的数据其中一个特性就是互异性,在判断两个对象是否相同时,Ruby默认采用的就是Object#eql?方法,而不是Object#equal?。
但有时你可能恰好想在一个集合里存放两个字面值相同但对象ID不同的变量时,这在Ruby 2.4之前是没法通过内置Set实现的。
require 'set'
set = Set.new #=> #<Set: {}>
str1 = "Sample string" #=> "Sample string"
str2 = str1.dup #=> "Sample string"
set.add(str1) #=> #<Set: {"Sample string"}>
set.add(str2) #=> #<Set: {"Sample string"}>
Ruby 2.4中引入了一个叫Set#compare_by_identity的方法,可以修改Set判断两个对象是否相同的标准,也就是用object_id_id作为判断依据,即Object#equal?。
require 'set'
set = Set.new.compare_by_identity #=> #<Set: {}>
str1 = "Sample string" #=> "Sample string"
str2 = str1.dup #=> "Sample string"
set.add(str1) #=> #<Set: {"Sample string"}>
set.add(str2) #=> #<Set: {"Sample string", "Sample string"}>
除了修改Set的判断标准外,还可以用Set#compare_by_identity?来查看一个Set对象采用的是那种判断标准。
require 'set'
set1= Set.new #=> #<Set: {}>
set2= Set.new.compare_by_identity #=> #<Set: {}>
set1.compare_by_identity? #=> false
set2.compare_by_identity? #=> true
-完-