codecamp

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类型检查程序将这些显式类型添加到方法和属性,您可以为安全,动态编程提供真正的坚实基础。

要更好地了解您可以在代码中使用哪些类型,以及在何处以及如何放置显式类型注释,请查看:

Hackificator
hack类型系统
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }