如何在 hacklang 中定义空 dict<string, int>

How to define empty dict<string, int> in hacklang

我有以下形状:

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

如何用空字典创建这个形状?例如从这个函数

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

不知道我使用了什么语言功能,但这确实有效。

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

如果有人有更多的上下文,请添加你的答案我会接受

This is a part of the Hack array proposal

A dict array is a container mapping a valid arraykey to a value. This mirrors the behavior of the Map class. This will be an array at runtime with extra restrictions to allow it to be used safely like a Map from the type checkers perspective. This focuses mainly on the desired runtime behavior, but if there are questions for how it will interact with the type checker I'll be happy to discuss. Literal Constructor

A dict is constructed using the literal expression dict[].

$dict = dict[]; // Empty dict-array
$dict = dict['a' => 1, 'b' => 2, 'c' => 3]; // dict-array of 3 elements

This is a static expression, so it can be used in a static initializer.

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 的键和值,因此它不会引发任何错误。

您还可以使用 vecdict 助手

从 php 样式的数组创建字典数组或向量
$array = [
    'a' => 1,
    'b' => 'c'
];

$dict = dict($array);

在上面的例子中,类型检查器知道 $array 中键的类型,并且由于 dict 助手被声明为 dict<Tk, Tv>(KeyedTraversable<Tk, Tv> $array): dict<Tk, Tv> 它知道返回的字典数组包含相同类型的键和值。

有时您可能无法告诉类型检查器数组键和值的类型。

示例:

$array = json_decode('path/to/file.json');

你知道 json 文件包含一个字符串键和值的数组,但这里类型检查器认为 $arraymixed 类型,因为没有办法实际上告诉文件里面有什么。

为了克服这个问题,您可以使用 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);