为什么 2 个相同的字符串在 Ruby 中具有相同的 object_id?
why 2 same strings have the same object_id in Ruby?
如您所知,在 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
正如您从结果中看到的那样,具有相同值 "one" 的 2 个字符串对象具有相同的 object_id 21641920,而它应该具有不同的 ID。那么谁能给我一些提示或告诉我在这种情况下如何获得不同的 ID?
最好的问候。
当 String
对象用作 Hash
中的键时,哈希将在内部复制和冻结字符串,并将该副本用作其键。
参考:Hash#store
.
从 ruby 2.2 开始,在哈希文字中用作键的字符串被冻结和去重:相同的字符串将被重复使用。
这是一个性能优化:不分配相同字符串的许多副本意味着要分配的对象和垃圾收集的对象更少。
查看冻结字符串文字的另一种方法:
"foo".freeze.object_id == "foo".freeze.object_id
在 ruby >= 2.1
的版本中 return 会是真的吗
如您所知,在 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
正如您从结果中看到的那样,具有相同值 "one" 的 2 个字符串对象具有相同的 object_id 21641920,而它应该具有不同的 ID。那么谁能给我一些提示或告诉我在这种情况下如何获得不同的 ID? 最好的问候。
当 String
对象用作 Hash
中的键时,哈希将在内部复制和冻结字符串,并将该副本用作其键。
参考:Hash#store
.
从 ruby 2.2 开始,在哈希文字中用作键的字符串被冻结和去重:相同的字符串将被重复使用。
这是一个性能优化:不分配相同字符串的许多副本意味着要分配的对象和垃圾收集的对象更少。
查看冻结字符串文字的另一种方法:
"foo".freeze.object_id == "foo".freeze.object_id
在 ruby >= 2.1
的版本中 return 会是真的吗