codecamp

Typechecker运行

运行Typechecker很简单。对于大多数用户和大多数用途,它是一个单行命令,称为hh_client。

hh_client

hh_client对于所有意图和目的,是类型检查器。假设您已正确安装所有内容,并且已将.hhconfig文件添加到代码库的根目录,然后启动typechecking:

%(root of codebase) hh_client

这是一些Hack代码的例子,它是如何被检查的。

<?hh

namespace Hack\UserDocumentation\TypeChecker\Running\Examples\Simple;

function a(int $x): int {
  return x + 1;
}
function main(): void {
  // simple-check.php:13:14,16: Invalid argument (Typing[4110])
  //   simple-check.php:5:12,14: This is an int
  //   simple-check.php:13:14,16: It is incompatible with a string
  a("5");

  // No errors!
  a(5);
}

main();

Output

Catchable fatal error: Argument 1 passed to Hack\UserDocumentation\TypeChecker\Running\Examples\Simple\a() must be an instance of int, string given in /data/users/joelm/user-documentation/guides/hack/25-typechecker/04-running-examples/simple-check.php.type-errors on line 7

我们来检查调用的错误消息a("5"):

simple-check.php:13:14,16: Invalid argument (Typing[4110])
  simple-check.php:5:12,14: This is an int
  simple-check.php:13:14,16: It is incompatible with a string

该Invalid argument行告诉您发现实际错误的位置。在我们的情况下,调用a("5")是什么导致错误。

注意:这Typing[4110]是服务器的状态码。这个代码可以用于这样的东西HH_FIXME

这一This is an int行让你知道typechecker预期你要做什么。基本上说你的电话a()应该提供一个int。

该It is incompatible with a string行让你知道你做了什么导致typechecker错误。在这种情况下,你通过了string以a()代替int。

hh_server

运行时hh_client,它会检查Typechecker服务器hh_server是否正在运行。如果没有,服务器将被转移。否则,将使用服务器的当前实例。

服务器是后台基础设施,用于对代码进行所有类型分析。是连续的 这就是为什么hh_client报告错误接近瞬间。

Hack文件类型检查

typechecker只检查Hack文件; 那就是开头的文件<?hh。所以如果你的代码库是全部的<?php,那么typechecker将不会对你有太多的用处,只会报告No errors!。

自动加载

Typechecker假设项目中的所有可用代码都可以在项目的任何地方使用。没有检查您的require和include语句是否准确和正确。如果不是,那么你将会在运行时被咬死。

当然,如果你的代码是一个文件,这一点是愚蠢的。但一旦你开始拥有多个文件自动加载的项目变得非常有用。如果您不自动加载,则Typechecker仍然会正确键入错误,但无法确定您忘记了包含一些必需代码的文件才能实际运行。

<?hh

namespace Hack\UserDocumentation\TypeChecker\Running\Examples\Autoloading;

class A {
  private B $b;
  public function __construct(B $b) {
    $this->b = $b;
  }
  public function foo(): int {
    return $this->b->getSomeInt();
  }
}

function callFoo(): void {
  $a = new A(new B());
  var_dump($a->foo());

}

function myAutoloader(string $class): void {
  // Remove all the namespace stuff and just get the 'B'
  include __DIR__ . '/' . substr($class, -1) . '.inc.php';
}

spl_autoload_register(
  'Hack\UserDocumentation\TypeChecker\Running\Examples\Autoloading\myAutoloader'
);

callFoo();

/*

<?hh

namespace Hack\UserDocumentation\TypeChecker\Intro\Examples\Autoloading;

class B {
  public function getSomeInt(): int {
    return 5;
  }
}

*/

Output

int(5)

假设我们忘了在这里要求访问类的代码B。没有自动加载代码,如果你运行hh_client,你会得到No errors!。太好了吧?嗯,不是真的 类型检查器做了正确的事情,但是你会在运行时死机

Fatal error: Class undefined: Hack\UserDocumentation\TypeChecker\Intro\Examples\Autoloading\B

通过自动加载包含的文件B,您可能会意外忘记requires,但您的代码仍将正确运行。

INT(5)


Typechecker Setup
Typechecker模式
温馨提示
下载编程狮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; }