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

我們創(chuàng)建一個(gè)新的Box。存儲(chǔ)一個(gè)int。然后存儲(chǔ)一個(gè)string。

直覺上,你會(huì)認(rèn)為類型檢查者應(yīng)該提出一個(gè)錯(cuò)誤。但它不!

在這里,我們存儲(chǔ)點(diǎn)string中unresolved(),我們有一個(gè)未解決的類型(見非通用懸而未決類型的討論在這里)。這意味著我們Box可能是一個(gè)Box<int>或一個(gè)Box<string>。我們還不知道。而且,由于我們從來沒有碰到與使用Boxin 有關(guān)的邊界unresolved(),typechecker只是繼續(xù)前進(jìn)。

typechecker通常在邊界上工作,它檢查方法調(diào)用帶有注釋參數(shù)的方法,它會(huì)return根據(jù)返回類型的類型注釋從函數(shù)中檢查我們。等等。

當(dāng)我們存儲(chǔ)string在resolved(),我們還沒有在邊界條件。只有當(dāng)我們調(diào)用一個(gè)函數(shù),期望Box<int>類型錯(cuò)誤將被拋出。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)