hack類型介紹

2018-10-01 22:01 更新

在用連詞typechecker,hack語言的打字能力是所有其他hack功能,可基石。開發(fā)Hack語言的主要動機是能夠明確地鍵入代碼的各個部分,以便可以分析代碼的類型一致性和可能的??錯誤。

采取這個前Hack的例子:

<?php

namespace Hack\UserDocumentation\Types\Intro\Examples\PreHack;

class Z {}
class A {
  public $a;
  public $b;

  public function __construct($a, $b) {
    $this->a = $a;
    $this->b = $b;
  }

  public function foo($x, $y) {
    return $x * $this->a + $y * $this->b;
  }
}

function bar(A $a, $x, $y) {
  return $a->foo($x, $y);
}

function baz() {
  $a = new A(2, 4);
  $z = new Z();
  var_dump(bar($a, 9, 4));
  // Did we really want to allow passing a stringy int?
  var_dump(bar($a, 8, "3"));
  // Did we really want to allow passing booleans?
  var_dump(bar($a, true, false));
  // This will throw a fatal at runtime
  var_dump(bar($z, 1, 1));
}

baz();

Output

int(34)
int(28)
ine(2)
Catchable fatal error: Argument 1 passed to Hack\UserDocumentation\Types\Intro\Examples\PreHack\bar() must be an instance of Hack\UserDocumentation\Types\Intro\Examples\PreHack\A, Hack\UserDocumentation\Types\Intro\Examples\PreHack\Z given in /data/users/joelm/user-documentation/guides/hack/20-types/01-introduction-examples/pre-hack.php on line 33

上面的例子是一個完全有效的程序,它將在HHVM上運行(除了最后發(fā)生的致命事件外var_dump)。但是,在許多情況下,程序員的意圖尚不清楚。例如,程序員真的想允許A::foo()接受string像int。當然,通過使用檢查is_int()或異常拋出可以發(fā)生緩解。

但是看下面這個例子來看看這個意圖有多清晰。

<?hh

namespace Hack\UserDocumentation\Types\Intro\Examples\Hack;

class Z {}
class A {
  public int $a;
  public int $b;

  public function __construct(int $a, int $b) {
    $this->a = $a;
    $this->b = $b;
  }

  public function foo(int $x, int $y): int {
    return $x * $this->a + $y * $this->b;
  }
}

function bar(A $a, int $x, int $y): int {
  return $a->foo($x, $y);
}

function baz(): void {
  $a = new A(2, 4);
  $z = new Z();
  var_dump(bar($a, 9, 4));
  // Did we really want to allow passing a stringy int? NO!
  // The typechecker will actually error here before you even run the program,
  // so you can catch problems before runtime.
  var_dump(bar($a, 8, "3"));

  // Did we really want to allow passing booleans? NO!
  // The typechecker will error here too.
  var_dump(bar($a, true, false));

  // This will throw a fatal at runtime
  // The typechecker will error here as well
  var_dump(bar($z, 1, 1));
}

baz();

/****

Type checker errors:

hack.php:29:23,25: Invalid argument (Typing[4110])
  hack.php:20:28,30: This is an int
  hack.php:29:23,25: It is incompatible with a string
hack.php:31:20,23: Invalid argument (Typing[4110])
  hack.php:20:20,22: This is an int
  hack.php:31:20,23: It is incompatible with a bool
hack.php:31:26,30: Invalid argument (Typing[4110])
  hack.php:20:28,30: This is an int
  hack.php:31:26,30: It is incompatible with a bool
hack.php:33:16,17: Invalid argument (Typing[4110])
  hack.php:20:14,14: This is an object of type
                     Hack\UserDocumentation\Types\Intro\Examples\Hack\A
  hack.php:26:8,14: It is incompatible with an object of type
                    Hack\UserDocumentation\Types\Intro\Examples\Hack\Z
*****/

Output

int(34)
Catchable fatal error: Argument 3 passed to Hack\UserDocumentation\Types\Intro\Examples\Hack\bar() must be an instance of int, string given in /data/users/joelm/user-documentation/guides/hack/20-types/01-introduction-examples/hack.php.type-errors on line 31

現(xiàn)在我們可以看到,意圖只是int通過了。雖然程序仍然像前面的例子一樣運行,但是這個API的用戶現(xiàn)在將知道預期的內(nèi)容。結合使用Hack類型檢查程序?qū)⑦@些顯式類型添加到方法和屬性,您可以為安全,動態(tài)編程提供真正的堅實基礎。

要更好地了解您可以在代碼中使用哪些類型,以及在何處以及如何放置顯式類型注釋,請查看:

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號