hack集合:hack arrays
hack提供额外的“阵列状”的类型:dict,vec,和keyset; 我们预计这些将最终替换收集对象,并且将被建议,一旦Hack标准库离开'预览'状态,它们将被使用 。
类型
- vec<T>是类型项目的可索引和可移动容器T; 它是作为替换的Vector,ImmVector和ConstVector
- dict<Tk as arraykey, Tv>是可转位和可键合的可移动容器的类型的项目Tv; 这是作为替换的Map,ImmMap和ConstMap。Tk必须是一个arraykey,即string或int键。
- keyset<T as arraykey>是一个可索引和键入的可移动容器的唯一项目类型T; 这是作为替换的Set,ImmSet和ConstSet。它只能包含arraykey值,即string或int。
所有这些类型都保留插入顺序。
创建Hack数组
文字用[]语法创建:
<?hh
namespace Hack\UserDocumentation\Collections\HackArrays\Examples\Literals;
function main(): void {
var_dump(vec[1, 2, 3, 1]);
var_dump(dict['a' => ord('a'), 'b' => ord('b'), 'c' => ord('c')]);
var_dump(keyset[1, 2, 3, 1]);
}
main();
Output
vec(4) {
int(1)
int(2)
int(3)
int(1)
}
dict(3) {
["a"]=>
int(97)
["b"]=>
int(98)
["c"]=>
int(99)
}
keyset(3) {
int(1)
int(2)
int(3)
}
此外,Hack还提供以下转换功能:
- vec<Tv>(Traversable<Tv>): vec<Tv>
- dict<Tk as arraykey, Tv>(KeyedTraversable<Tk, Tv>): dict<Tk, Tv>
- keyset<Tv as arraykey>(Traversable<Tv>): keyset<Tv>
<?hh
namespace Hack\UserDocumentation\Collections\HackArrays\Examples\Conversions;
function main(): void {
var_dump(vec(Vector { 1, 2, 3, 1 }));
var_dump(dict(Map {'a' => ord('a'), 'b' => ord('b'), 'c' => ord('c') }));
var_dump(keyset(Vector {1, 2, 3, 1 }));
var_dump(keyset(Set {1, 2, 3, 1 }));
}
main();
Output
vec(4) {
int(1)
int(2)
int(3)
int(1)
}
dict(3) {
["a"]=>
int(97)
["b"]=>
int(98)
["c"]=>
int(99)
}
keyset(3) {
int(1)
int(2)
int(3)
}
keyset(3) {
int(1)
int(2)
int(3)
}
Library功能
由于Hack Arrays不是对象,它们没有方法。Library支持通过Hack标准库提供。
完整的API参考是自动生成的,但我们强烈建议您先阅读 README。
与hack集合相比
hack集合(Vector,Map,Set,...)都是对象; hack阵列(vec,dict,keyset)是值。主要影响是:
- Hack集合通过引用隐式传递
- Hack数组通过值隐含地传递,具有类似写入的行为
- Hack数组没有方法,需要库函数
- 没有必要Const或Imm变体的Hack数组
引用和写时复制语义之间的区别如下所示:
<?hh
namespace Hack\UserDocumentation\Collections\HackArrays\Examples\RefVsCow;
function do_stuff($container) {
$container[] = 456;
return $container;
}
function main(): void {
$a = Vector { 123 };
$b = do_stuff($a);
$x = vec[123];
$y = do_stuff($x);
var_dump([
array(
'in' => $a,
'out' => $b,
'mutated' => $a == $b,
),
array(
'in' => $x,
'out' => $y,
'mutated' => $x == $y,
),
]);
}
main();
Output
array(2) {
[0]=>
array(3) {
["in"]=>
object(HH\Vector)#1 (2) {
[0]=>
int(123)
[1]=>
int(456)
}
["out"]=>
object(HH\Vector)#1 (2) {
[0]=>
int(123)
[1]=>
int(456)
}
["mutated"]=>
bool(true)
}
[1]=>
array(3) {
["in"]=>
vec(1) {
int(123)
}
["out"]=>
vec(2) {
int(123)
int(456)
}
["mutated"]=>
bool(false)
}
}
与PHP数组相比
- Hack数组不会将int类型的字符串键隐式转换为int
当未定义的索引被访问时,hack数组会显示异常,而不是返回null。
- 不能包含引用
禁止引用的证明如下:
<?hh
namespace Hack\UserDocumentation\Collections\HackArrays\Examples\CanNotContainReferences;
function foo(int &$foo) {
$foo = 346;
}
$y = vec[1,2,3];
foo($y[2]);
var_dump($y);
Output
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Vecs cannot contain references' in /Users/fredemmott/code/user-documentation/guides/hack/23-collections/11-hack-arrays-examples/can-not-contain-references.php:10
Stack trace:
#0 {main}
Examples