Сегодня мы разберемся с типизированными хешами, но сначала позвольте напомнить, как указать тип простой скалярной переменной:
my Int $i;
Аналогично можно указать тип данных, который вы назначаете допустимым для элементов массива:
> my Int @i; [] > @i.push(42); [42]
Если попытаться в этот массив добавить строку, произойдет ошибка:
> @i.push('Hello'); Type check failed in assignment to @i; expected Int but got Str ("Hello") in block <unit> at <unknown file> line 1
А вот с хешами чуть сложнее, потому что у каждого элемента хеша два элемента: ключ и значение.
Чтобы указать тип значений, используется вот такой синтаксис:
my Str %s;
Теперь мы можем хранить строки:
> %s<Hello> = 'World' World > %s<42> = 'Fourty-two' Fourty-two
Но не числа:
> %s<x> = 100 Type check failed in assignment to %s; expected Str but got Int (100) in block <unit> at <unknown file> line 1
(Обратите внимание, что ключом в %s<42> тоже является строка, а не число.)
А чтобы указать тип ключей, поставьте его имя в фигурных скобках:
my %r{Rat};
У нас получился типизированный, или объектный хеш.
Например, создадим хеш, где ключами будут работать значения типа Rat:
> %r<22/7> = pi 3.14159265358979 > %r {22/7 => 3.14159265358979}
Теперь уже невозможно использовать ни целые числа, ни строки:
> %r<Hello> = 1 Type check failed in binding to parameter 'key'; expected Rat but got Str ("Hello") in block <unit> at <unknown file> line 1 > %r{23} = 32 Type check failed in binding to parameter 'key'; expected Rat but got Int (23) in block <unit> at <unknown file> line 1
И, наконец, еще более ограничим элементы хеша, указав одновременно и тип ключей, и тип значений:
my Str %m{Int};
Ключи здесь — целые числа, а значения — строки. Например, в этом хеше теперь можно хранить соответствие номеров месяцев их названиям, но не наоборот:
> %m{3} = 'March' March > %m<March> = 3 Type check failed in binding to parameter 'key'; expected Int but got Str ("March") in block <unit> at <unknown file> line 1