为什么2个相同的字符串在Ruby中具有相同的object_id?

时间:2015-05-09 10:34:19

标签: ruby string hash symbols

您可能知道在Ruby中,两个相同的字符串没有相同的object_id,而两个相同的符号则相同。例如:

irb(main):001:0> :george.object_id == :george.object_id
=> true
irb(main):002:0> "george".object_id == "george".object_id
=> false

但是,在我的下面的代码中,它显示了具有相同值“one”的两个字符串具有相同的object_id。

class MyArray < Array
    def ==(x)
        comparison = Array.new()
        x.each_with_index{|item, i| comparison.push(item.object_id.equal?(self[i].object_id))}
        if comparison.include?(false) then
            false
        else
            true
        end
    end
end
class MyHash < Hash
    def ==(x)
         y = Hash[self.sort]
        puts y.class
        puts y
        x = Hash[x.sort]
        puts x.class
        puts x
puts "______"
        xkeys = MyArray.new(x.keys)
        puts xkeys.class
        puts xkeys.to_s
        puts xkeys.object_id

        puts xkeys[0].class
        puts xkeys[0]
        puts xkeys[0].object_id
puts "______"
        xvals = MyArray.new(x.values)
puts "______"
        selfkeys = MyArray.new(y.keys)
        puts selfkeys.class
        puts selfkeys.to_s
        puts selfkeys.object_id

        puts selfkeys[0].class
        puts selfkeys[0]
        puts selfkeys[0].object_id
puts "______"
        selfvals = MyArray.new(y.values)
puts xkeys.==(selfkeys)
puts xvals.==(selfvals)
    end
end


 a1 = MyHash[{"one" => 1, "two" => 2}]
 b1 = MyHash[{"one" => 1, "two" => 2}]
 puts a1.==(b1)

获取

Hash
{"one"=>1, "two"=>2}
Hash
{"one"=>1, "two"=>2}
______
MyArray
["one", "two"]
21638020
String
one
21641920
______
______
MyArray
["one", "two"]
21637580
String
one
21641920
______
true
true

从结果可以看出,2个String对象具有相同的值“one”具有相同的object_id 21641920,而它应该具有不同的ID。所以任何人都可以给我一些提示或告诉我如何在这种情况下获得不同的ID? 最诚挚的问候。

2 个答案:

答案 0 :(得分:6)

String对象用作Hash中的键时,哈希将在内部复制并冻结该字符串,并将该副本用作其密钥。

参考:Hash#store

答案 1 :(得分:2)

从ruby开始,用作散列文字中的键的2.2字符串被冻结和重复数据删除:将重用相同的字符串。

这是一种性能优化:不分配相同字符串的许多副本意味着要分配的对象更少,垃圾回收更少。

另一种查看冻结字符串文字的方法:

"foo".freeze.object_id == "foo".freeze.object_id

将在ruby&gt; = 2.1

的版本中返回true