hack集合:Typing
您通常将通过具体类实例化Hack集合对象。但是,什么参数类型被接受或从方法返回可能是其中一个接口。
以下示例显示如何将任何具体的类传递给需要的函数Iterable<T>。在这些情况下T,代表每个集合的值的类型。所以int对于$v和string为$m。对于地图,在这种情况下,键的类型并不重要。
<?hh
namespace Hack\UserDocumentation\Collections\Typing\Examples\Iter;
// Given that this function takes an Iterable, you can pass any of
// our current concerte collection classes to this method
function take_iterable<T>(Iterable<T> $it): array<T> {
return $it->toValuesArray();
}
function run(): void {
$v = Vector {100, 200, 300};
var_dump(take_iterable($v));
$iv = ImmVector {400, 500, 600};
var_dump(take_iterable($iv));
$s = Set {'A', 'B'};
var_dump(take_iterable($s));
$is = ImmSet {'C', 'D'};
var_dump(take_iterable($is));
$m = Map {'A' => 'Z', 'B' => 'Y'};
var_dump(take_iterable($m));
$im = ImmMap {'C' => 'X', 'D' => 'W'};
var_dump(take_iterable($im));
}
run();
Output
array(3) {
[0]=>
int(100)
[1]=>
int(200)
[2]=>
int(300)
}
array(3) {
[0]=>
int(400)
[1]=>
int(500)
[2]=>
int(600)
}
array(2) {
[0]=>
string(1) "A"
[1]=>
string(1) "B"
}
array(2) {
[0]=>
string(1) "C"
[1]=>
string(1) "D"
}
array(2) {
[0]=>
string(1) "Z"
[1]=>
string(1) "Y"
}
array(2) {
[0]=>
string(1) "X"
[1]=>
string(1) "W"
}
以下示例显示了如何使用它ConstVector来确保传递不能修改的向量。你可能会问为什么不注释它ImmVector?那是因为你可以想象未来实施的其他不变的向量 并且由于所有不可变的向量必须实现ConstVector,所以更具有表现力ConstVector。返回类型也采用相同的理由MutableVector。
现在,如果你知道这个函数只会占用一个ImmVector现在和永远,那么键入注释ImmVector就可以了。
<?hh
namespace Hack\UserDocumentation\Collections\Typing\Examples\CV;
// Given that this function takes a ConstVector, you can pass any concrete
// collection that implements the interface (currently Vector and ImmVector)
function filter_vec(\ConstVector<int> $cv): \MutableVector<int> {
try {
$cv[] = 900; // cannot modify a ConstVector
} catch (\InvalidOperationException $ex) {
var_dump($ex->getMessage());
}
$mv = $cv->filter($x ==> $x % 4 === 0);
return $mv->toVector();
}
function run(): void {
$iv = ImmVector {100, 125, 150, 175};
var_dump(filter_vec($iv));
}
run();
Output
string(51) "Cannot modify immutable object of type HH\ImmVector"
object(HH\Vector)#5 (1) {
[0]=>
int(100)
}