Хеш
Хеш — это обобщённая коллекция пар «ключ-значение», сопоставляющая ключи типа K значениям типа V.
Хеши обычно создаются с помощью литерала хеша, обозначаемого фигурными скобками ({ }), в которых заключён список пар; для разделения ключа и значения используется =>, а сами пары разделяются запятыми ,.
{"one" => 1, "two" => 2}
Аргумент обобщённого типа
Аргументы обобщённого типа для ключей K и значений V выводятся соответственно из типов ключей и значений внутри литерала. Если все они имеют один и тот же тип, K/V будет равен ему. В противном случае это будет объединение всех типов ключей или, соответственно, значений.
{1 => 2, 3 => 4} # Hash(Int32, Int32)
{1 => 2, 'a' => 3} # Hash(Int32 | Char, Int32)
Явные типы можно указать сразу после закрывающей скобки, добавив of (отделённый пробелом), тип ключа (K), за которым следует => в качестве разделителя, и тип значения (V). Это переопределяет выведенные типы и, например, позволяет создать хеш, который изначально содержит только некоторые типы, но может принимать и другие типы.
Для пустых литералов хеша всегда необходимо указывать типы:
{} of Int32 => Int32 # => Hash(Int32, Int32).new
Литерал типа, подобного хешу
Crystal поддерживает дополнительный литерал для хешей и типов, подобных хешам. Он состоит из имени типа, за которым следует список пар «ключ-значение», разделённых запятыми и заключённых в фигурные скобки ({}).
Hash{"one" => 1, "two" => 2}
Этот литерал можно использовать с любым типом, если у него есть конструктор без аргументов и он отвечает на вызов []=.
HTTP::Headers{"foo" => "bar"}
Для негenericного типа, например HTTP::Headers, это эквивалентно следующему:
headers = HTTP::Headers.new
headers["foo"] = "bar"
Для обобщённого типа обобщённые типы выводятся из типов ключей и значений таким же образом, как и для литерала хеша.
MyHash{"foo" => 1, "bar" => "baz"}
Если MyHash является обобщённым, приведённый выше вариант эквивалентен следующему:
my_hash = MyHash(typeof("foo", "bar"), typeof(1, "baz")).new
my_hash["foo"] = 1
my_hash["bar"] = "baz"
Аргументы типов можно явно указать как часть имени типа:
MyHash(String, String | Int32){"foo" => "bar"}
To the extent possible under law, the persons who contributed to this workhave waived
all copyright and related or neighboring rights to this workby associating CC0 with it.
https://crystal-lang.org/reference/1.2/syntax_and_semantics/literals/hash.html