Это часть предложения по массиву Hack
Массив dict - это контейнер, сопоставляющий действительный ключ массива со значением.Это отражает поведение класса Map.Это будет массив во время выполнения с дополнительными ограничениями, позволяющими безопасно использовать его, например, Map с точки зрения проверки типов.Это сосредоточено главным образом на желаемом поведении во время выполнения, но если будут вопросы о том, как оно будет взаимодействовать с средством проверки типов, я буду рад обсудить.Конструктор литералов
Диктовка создается с использованием литерального выражения dict [].
$dict = dict[]; // Empty dict-array
$dict = dict['a' => 1, 'b' => 2, 'c' => 3]; // dict-array of 3 elements
Это статическое выражение, поэтому его можно использовать в статическом инициализаторе.
class C {
public static dict<string, int> $dict = dict[
'a' => 1,
'b' => 2,
'c' => 3,
];
}
source: https://github.com/facebook/hhvm/issues/6452
Вам не нужно определять тип при создании словарей (dict[]
) или векторов (vec[]
), так как обобщенные значения игнорируются во время выполнения
Пример:
function spamMessages(dict<string, string> $messages): void
{
foreach($messages as $user => $message) {
echo $user . ': ' . $message;
}
}
function listUsers(vec<string> $users): void
{
foreach($users as $user) {
echo '-' . $user;
}
}
$messages = dict[
'azjezz' => 'bring the cookies'
];
$users = vec[
'azjezz'
];
spamMessages($messages);
listUsers($users);
В этом примере средство проверки типов достаточно умен, чтобы видеть, что у $message
есть и ключи, и значения типа string
, поэтому он не вызовет никаких ошибок.
Вы также можете создать массив dict или вектор из массива в стиле php, используя помощники vec
и dict
$array = [
'a' => 1,
'b' => 'c'
];
$dict = dict($array);
В приведенном выше примере средство проверки типов знаето типе ключей в $array
, и поскольку помощник dict
объявлен как dict<Tk, Tv>(KeyedTraversable<Tk, Tv> $array): dict<Tk, Tv>
, он знает, что возвращенный массив dict содержит одинаковые типы для ключей и значений.
Иногда вы можетене сможет рассказать контролеру типов о типах ключей массиваи значения.
Пример:
$array = json_decode('path/to/file.json');
Вы знаете, что, например, файлы json содержат массив строковых ключей и значений, но здесь средство проверки типов считает, что $array
имеет тип mixed
, поскольку на самом деле невозможно определить, что находится внутри файла.
Чтобы преодолеть это, вы можете использовать оператор as
, чтобы сообщить контролеру типов о $array
type
$array = json_decode('path/to/file.json') as array<_, _>;
Обратите внимание, что здесь мы использовали _
вместо string
, и они проверят, что тип $array
теперь имеет тип array<arraykey, mixed>
, причина в том, что обобщения не поддерживаются оператором as
на данный момент, но это может измениться в будущем, поэтому мы можем сделать as array<string, string>
Позже вы можете создать дикт из этого массива:
$dict = dict($array);
Если вы, например, знаете, что естьэтот файл не может содержать ничего кроме строковых ключей и значений и требует принудительного ввода этого типа. Вы можете использовать следующий помощник для приведения его к типу dict<string, string>
, но я не буду рекомендовать его, поскольку это может вызвать ошибкуво время каста non-stringable
объекты или ресурсы для строки.
// KeyedContainer = array, dict, maps and other keyed containers
function forceStringDict(KeyedContainer<arraykey, mixed> $container): dict<string, string>
{
$dict = dict[];
foreach($container as $k => $v) {
$dict[(string) $k] = (string) $v;
}
return $dict;
}
$dict = forceStringDict($dict);