Как определить пустой диктв хакланге - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть следующая форма:

const type A = shape(
  'b' => dict<string, int>,
);

Как мне создать эту форму с пустым диктом?Например из этой функции

function getA(): A {
  return shape(
    'b' => ???
  );
}

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Это часть предложения по массиву 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);
0 голосов
/ 20 сентября 2018

Понятия не имею, какие языковые функции я использовал, но это помогает.

function getA(): A {
  return shape(
    'b' => dict[]
  );
}

Если у кого-то есть больше контекста, пожалуйста, добавьте свой ответ, я его приму

...