lazybios

Set#compare_by_identity | Ruby 2.4

在Ruby中,我们可以使用Object#equal?方法去判断两个对象是否完全相同,同时Ruby还有一个叫Object#eql?的方法,它用来判断两个对象是否含有相同的值。

str1 = "Sample string"
str2 = str1.dup

str1.eql?(str2)     #=> true

str1.equal?(str2)   #=> false

通过object_id可以清楚的看出str1str2是两个不同的对象。

str1.object_id      #=> 70334175057920

str2.object_id      #=> 70334195702480

Set对象中的数据其中一个特性就是互异性,在判断两个对象是否相同时,Ruby默认采用的就是Object#eql?方法,而不是Object#equal?

但有时你可能恰好想在一个集合里存放两个字面值相同但对象ID不同的变量时,这在Ruby 2.4之前是没法通过内置Set实现的。

Ruyb 2.3

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?

Ruby 2.4

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#compare_by_identity?

除了修改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

-完-

参考引用

微信关注「日拱一卒」公众号