2015-05-09 64 views
3

正如你可能知道在Ruby中,两个相同的字符串没有相同的object_id,而两个相同的符号。例如:为什么2个相同的字符串在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对象与具有相同的价值“一”有相同的object_id 21641920,而它应该有不同的ID,结果看到的。所以任何人都可以给我一些提示或者告诉我在这种情况下我如何得到不同的ID? 最好的问候。

回答

6

当某个String对象用作Hash中的键时,散列将在内部复制并冻结该字符串,并将该副本用作其键。

参考:Hash#store

+0

那么你知道如何编辑代码即可获得假的,真正的结果,而不是真实的,真实的。实际上,我尝试在MAC pc上运行这个代码,并且它返回false,true但不是true,就像在Wins OS中一样。 – weefwefwqg3

+1

@匿名通信我还没有找到该引用,但我认为散列内部使用的“String”对象类似于C/C++中的字符串文字,具有相同内容的字符串文字可能存储在相同地址,可能存储在不同的地址,行为是实现定义的。 –

2

作为ruby 2.2在散列字面值中用作键的字符串被冻结和去重复:相同的字符串将被重用。

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

另一种查看冷冻字符串文字在行动:

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

将红宝石版本返回true> = 2.1

相关问题