2015-05-09 60 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

相關問題