我正在尝试一个简单的嵌套字典,然后读取一个嵌套值
$response = dict[
'some_other_key' => 'asdf',
'sub_response' => dict['success' => false],
];
if ($response['sub_response']['success']){
// do stuff
}
我被这个错误弄糊涂了:
Typing[4324] Invalid index type for this array [1]
-> Expected int [2]
-> This can only be indexed with integers [3]
-> But got string [2]
40 |
41 | $response = dict[
[3] 42 | 'some_other_key' => 'asdf',
43 | 'sub_response' => dict['success' => false],
44 | ];
45 |
[1,2] 46 | if ($response['sub_response']['success']) {
47 | return $response;
48 | }
1 error found.
它似乎读错了键,并抱怨这是一根绳子?我做错了什么?
在Hack中,字典的每个键和每个值都有相同的类型;对于不均匀的用例,形状可能更合适。换句话说,字典很适合将一堆用户ID映射到相应的用户对象(dict<int, User>
(——这是一组统一的映射,但你不知道键的数量或具体是什么,其中您提前知道您拥有哪些密钥(some_other_key
、sub_response
(,因此类型检查器可以跟踪每个密钥的类型。
文件中提到了这一点,尽管它被掩盖了,也不清楚IMO:
如果您希望不同的关键点具有不同的值类型,或者如果您想要一组固定的关键点,请考虑使用形状。
所以这里发生的是,类型检查器试图推断$response
的类型。当然,它们的键是string
,但它确实对值感到困惑。有时您将其用作dict<string, string>
,有时用作dict<string, dict<string, bool>>
——这是不允许的。
尽管这段代码确实有错误,但消息非常令人困惑(可能值得提交一个bug(。我认为你是对的,类型检查器认为$response['sub_response']
必须是字符串,所以['success']
无效?但奇怪的是,它不会为$response
推断出dict<string, mixed>
的类型——这是$response
的有效类型,尽管仍然不是您想要的,但它可能会给出更好的错误消息。
在任何情况下,您似乎想要的是一个形状,其中每个单独键的类型都被单独跟踪。这是你想要的,我认为:
$response = shape(
'some_other_key' => 'asdf',
'sub_response' => dict['success' => false],
);
if ($response['sub_response']['success']){
// do stuff
}
(您可能还希望sub_response
是一种形状,这取决于您最终使用它的方式。(