Подтвердить что ты не робот

Использование целых чисел в качестве хеш-ключей

Уместно ли использовать целые числа в качестве ключей в хеше Ruby?

Каждый пример из документации показывает строку или символ, используемые в качестве ключа, но не целое.

Внутренне ли целые числа каким-то образом преобразуются в строки? Я видел некоторую противоречивую информацию по этому вопросу.

Другими словами, существует ли существенный недостаток использования целых ключей для хэша?

4b9b3361

Ответ 1

конечно, вы можете использовать целые числа в качестве ключей...

h = {1 => 'one', 2 => 'two', 3 => 'three'}

(1..3).each do |i|
  puts h[i]
end

= >

one
two
there

irb - ваш друг! попробуйте.


Фактически вы можете использовать любой объект Ruby как ключ (или значение). Обычно мы не думаем об использовании хэшей, но это может быть очень полезно.

Ответ 2

Другим, кто смотрит на ответы здесь, может быть интересно узнать, что исключение происходит, когда вы используете целые числа в качестве символьных ключей в Ruby hash {symbol: value}

hash = {1: 'one'} # will not work  
hash = {1 => 'one'} # will work

Запрошенное объяснение:

Самый простой ответ на вопрос, почему первый пример завершился неудачно, вероятно, что to_sym не является методом, который был реализован для Fixnum целых чисел.

Чтобы углубляться, чтобы объяснить, почему это так, одним из основных преимуществ использования символов является то, что два символа на самом деле являются "одним и тем же объектом". Или, по крайней мере, они имеют одинаковые идентификаторы объектов.

:foo.object_id == :foo.object_id
=> true

Строки, которые одинаковы, не используют одни и те же объекты и поэтому не имеют одинаковых идентификаторов объектов.

"foo".object_id == "foo".object_id
=> false

Подобные символы, целые числа Fixnum, которые являются одинаковыми, будут иметь одинаковые идентификаторы объектов. Поэтому вам не нужно преобразовывать их в символы.

one = 1
=> 1
uno = 1
=> 1
one.object_id
=> 3
one.object_id == uno.object_id
=> true

Ответ 3

Единственным требованием для использования объекта как хэш-ключа является то, что он должен отвечать на хэш сообщения с хэш-значением, а хеш-значение для данного ключа не должно меняться. Например, если вы вызываете это:

1.hash()

Вы можете видеть, что номер 1 действительно отвечает на хэш-сообщение

Ответ 4

Уже есть ответы на is it possible?.

Объяснение, почему нет примеров с целыми числами как хэш-ключи.

Хэш-ключи имеют (большую часть времени) значение. Это может быть имя атрибута и его значение (например, :color => 'red'...).

Когда у вас есть целое число в качестве ключа, ваша семантика может быть "первая, вторая..." (1). Но тогда вы не используете хэш, а массив для хранения ваших значений.

(1) Контрпример может быть внешним ключом в базе данных.