2015-05-03 5 views
0

Я использую Ruby 2.2.2.Ruby, hash and object_id

irb(main):002:0> str = "abc" 
=> "abc" 
irb(main):003:0> str2 = "abc" 
=> "abc" 
irb(main):004:0> str.hash 
=> -340360941 
irb(main):005:0> str2.hash 
=> -340360941 
irb(main):006:0> str.object_id 
=> 3702564 
irb(main):007:0> str2.object_id 
=> 24864312 
irb(main):009:0> str == str2 
=> true 
irb(main):010:0> str.eql? str2 
=> true 

str Почему и str2 имеют тот же хэш, но разные object_id? Согласно документам hash и object_id, ни один активный объект не будет делиться идентификатором, поэтому str и str2 имеют разные object_id, но как их понимать hash такие же?

Не могли бы вы рассказать об этом? Я предполагаю, что "abc" занимают только одно пространство памяти, и оба str и str2 относятся к тому же пространству памяти.

Если кто-то может объяснить это как распределить память, это будет здорово.

+0

Две различные объекты, равные должны иметь одинаковое значение хеш-функции. – Santhosh

+0

@Santhosh Полностью согласен. Не могли бы вы объяснить разницу между 'hash' и' object_id'? – coderz

ответ

2

Я думаю, что «а» занимают только одну области памяти, и оба str и str2 ссылаются на тот же объем памяти.

Было ли это так, их object_id были одинаковыми. Строка создается дважды и экземпляр str не имеет никакого отношения к экземпляру str2. В противном случае str[1] = "A" привел к изменению обеих переменных, преобразуя значение str2 в значение aAc.

Когда значение объектов равно, их хэш должны быть одинаковыми для быстрого поиска/поиска и т.д.

Э.Г. Джон Смит из Огайо и Джон Смит из Оклахомы имеют одно и то же имя, что делает их hash равными, но поскольку они определенно не являются одним и тем же лицом, их object_id отличаются.

+0

Это означает, что 'str' и' str2' занимают только одно пространство памяти, они имеют один и тот же адрес памяти, верно? – coderz

+1

Еще раз. Независимо от того, используют ли они один и тот же адрес памяти, любые изменения, применяемые к 'str', отражаются в' str2'. Это совершенно разные объекты, занимающие разные пространства памяти и не имеющие ничего общего в целом. 'str == str2' оценивается как' true' из-за особой реализации ['String # =='] (http://ruby-doc.org/core-1.9.3/String.html#method-i- 3D-3D), который, по-видимому, сравнивает _values_. – mudasobwa

0

object_id (и соответствующий метод equal?) связаны с идентификацией объекта: являются ли эти 2 объекта одним и тем же объектом? подклассы не (или, по крайней мере, не должны) переопределять это.

С другой стороны, == и eql? - это дополнительные сведения о значениях объекта: имеют ли эти два объекта одинаковое значение? Это, конечно, зависит от класса, поэтому вполне возможно, что в этом отношении есть два разных объекта (их object_id - разные). Контракт метода hash, равный объекту, должен иметь равное хэш-значение для eql?, поэтому нормально, что два объекта могут иметь разные объекты object_id, но имеют одинаковый хеш.

В вашем примере ваши 2 строки различные объекты, которые, в данный конкретный момент времени, случается, содержат ту же последовательность байтов