hack泛型:Unresolved
想象一下泛型Box类的以下用法
<?hh
namespace Hack\UserDocumentation\Generics\Unresolved\Examples\Unresolved;
class Box<T> {
private array<T> $contents;
public function __construct() {
$this->contents = array();
}
public function addTo(T $item) {
$this->contents[] = $item;
}
public function get(): array<T> {
return $this->contents;
}
}
function add_box_of_ints(Box<int> $box): int {
return array_sum($box->get());
}
function unresolved(): void {
$box = new Box();
// You might think that T has been bound to int, but no.
$box->addTo(4);
// Now we are unresolved. The typechecker knows we are using Box as a
// container of ints and now strings. Do we have a mixed Box?
$box->addTo('Hi');
// Well, we are not at a boundary, so the typechecker just let's this go.
}
function resolved(): void {
$box = new Box();
// You might think that T has been bound to int, but no.
$box->addTo(4);
// Now we are unresolved. The typechecker knows we are using Box as a
// container of ints and now strings. Do we have a mixed container?
$box->addTo('Hi');
// still unresolved
$box->addTo(99);
// Here we are resolved! add_box_of_ints is expecting a Box<int> and we
// don't have it. Now the typechecker can issue an error about adding the
// string
var_dump(add_box_of_ints($box));
}
function run(): void {
unresolved();
resolved();
}
run();
Output
Catchable fatal error: Value returned from function Hack\UserDocumentation\Generics\Unresolved\Examples\Unresolved\add_box_of_ints() must be of type int, float given in /data/users/joelm/user-documentation/guides/hack/40-generics/06-unresolved-examples/unresolved.php.type-errors on line 19
我们创建一个新的Box。存储一个int。然后存储一个string。
直觉上,你会认为类型检查者应该提出一个错误。但它不!
在这里,我们存储点string中unresolved(),我们有一个未解决的类型(见非通用悬而未决类型的讨论在这里)。这意味着我们Box可能是一个Box<int>或一个Box<string>。我们还不知道。而且,由于我们从来没有碰到与使用Boxin 有关的边界unresolved(),typechecker只是继续前进。
typechecker通常在边界上工作,它检查方法调用带有注释参数的方法,它会return根据返回类型的类型注释从函数中检查我们。等等。
当我们存储string在resolved(),我们还没有在边界条件。只有当我们调用一个函数,期望Box<int>类型错误将被抛出。