Hash (хэш) представляет собой структуру данных, отображающую ключи типа K в значения типа V. Обычно создается с помощью литерала хэша:
{1 => 2, 3 => 4}     # Hash(Int32, Int32)
{1 => 2, 'a' => 3}   # Hash(Int32 | Char, Int32)
Hash может иметь смешанные типы для ключей и значений. Это означает, что K или V будет объединением типов. Они определяются при создании хэша: либо при явном определении K и V, либо при использовании литерала хэша. В последнем случае K будет определен объединением ключей литерала хэша, а V - значений литерала хэша.
При создании пустого хэша необходимо явно определить K и V:
{} of Int32 => Int32 # то же, что и Hash(Int32, Int32).new
{}                   # синтаксическая ошибка
Специальная нотация разрешает создание хэша с символьными ключами:
{key1: 'a', key2: 'b'} # Hash(Symbol, Char)
Специальная нотация разрешает создание хэша со строковыми ключами:
{"key1": 'a', "key2": 'b'} # Hash(String, Char)
Вы можете использовать специальный синтаксис литерала хэша также с другими типами, до тех пор, пока у них определены методы new (без аргументов) и []=:
MyType{"foo": "bar"}
Если MyType не универсальный тип, то запись выше эквивалентна этой записи:
tmp = MyType.new
tmp["foo"] = "bar"
tmp
Если тип MyType универсальный, то эквивалентна этой записи:
tmp = MyType(typeof("foo"), typeof("bar")).new
tmp["foo"] = "bar"
tmp
В случае универсального типа, типы аргументов также могут быть определены:
MyType(String, String) {"foo": "bar"}