在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
-完-