hack泛型:Unresolved

2018-11-17 10:53 更新

想象一下泛型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>类型错误将被抛出。


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号