hack类型介绍
在用连词typechecker,hack语言的打字能力是所有其他hack功能,可基石。开发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上运行(除了最后发生的致命事件外var_dump)。但是,在许多情况下,程序员的意图尚不清楚。例如,程序员真的想允许A::foo()接受string像int。当然,通过使用检查is_int()或异常抛出可以发生缓解。
但是看下面这个例子来看看这个意图有多清晰。
<?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
现在我们可以看到,意图只是int通过了。虽然程序仍然像前面的例子一样运行,但是这个API的用户现在将知道预期的内容。结合使用Hack类型检查程序将这些显式类型添加到方法和属性,您可以为安全,动态编程提供真正的坚实基础。
要更好地了解您可以在代码中使用哪些类型,以及在何处以及如何放置显式类型注释,请查看: