hack高級規(guī)則

2018-10-04 12:29 更新

類型檢查規(guī)則通常很簡單(例如,不能傳遞string給期望的內(nèi)容int)。然而,有一些規(guī)則有一些更高級的語義。

軟類型提示

看看這個例子:

<?hh

namespace Hack\UserDocumentation\Types\AdvancedRules\Examples\SoftHint;

// HHVM will throw a warning instead of fatal if, for example, a bool is passed
// in
function foo(@int $x): bool {
  return $x < 5 ? true : false;
}

function call_foo(): void {
  foo(5);
  foo(false);
}

call_foo();

Output

Warning: Argument 1 to Hack\UserDocumentation\Types\AdvancedRules\Examples\SoftHint\foo() must be of type @int, bool given in /data/users/joelm/user-documentation/guides/hack/20-types/08-advanced-rules-examples/softhint.php.type-errors on line 9

前面的“@”是什么意思?這導(dǎo)致HHVM在傳遞的參數(shù)不匹配時觸發(fā)警告(因此始終繼續(xù)執(zhí)行)而不是可捕獲的致命錯誤。它用于允許您慢慢添加類型到您的代碼。

軟類型提示對類型檢查器行為沒有影響。如果類型不匹配,類型檢查器仍然會拋出錯誤。

Superglobals

無論你目前在什么范圍內(nèi),Superglobals都可以使用。

<?hh

namespace Hack\UserDocumentation\Types\AdvancedRules\Examples\SuperGlobals;

function get_superglobal(string $s): array<string> {
  // If you try to use a variable that doesn't exist (e.g., $_NOEXIST), the
  // typechecker will thrown an undefined variable error.
  switch ($s) {
    case '_GET':
      return $_GET;
      break;
    case '_ENV':
      return $_ENV;
      break;
    case '_SERVER':
      return $_SERVER;
      break;
    default: // not supporting anything else
      return array();
  }
}

function sg(string $s): array<string> {
  return get_superglobal($s);
}

var_dump(is_array(sg('_SERVER')));

Output

bool(true)

類型檢查器知道內(nèi)置超幀。

在Hack的嚴(yán)格模式下,superglobals不支持。所以你必須創(chuàng)建一些類似部分模式的功能,以從嚴(yán)格的模式文件中調(diào)用。

可以使用將PSR-7暴露給Hack 的存儲庫來實(shí)現(xiàn)使用superglobals的不完美但可行的替代方案。這個repo中的HHI文件給出了關(guān)于接口的Hack類型檢查器信息。

可變參數(shù)

Hack支持可變參數(shù)

function foo(<any explicit arguments>, int ...$args) // $args is a list of int arguments

類型檢查器將強(qiáng)制執(zhí)行可變類型,但是對于性能,運(yùn)行時不會。

<?hh

namespace Hack\UserDocumentation\Types\AdvancedRules\Examples\Variadic;

function foo(int ...$args): vec<int> {
  $ret = vec[];
  foreach ($args as $arg) {
    $ret[] = $arg;
  }
  return $ret;
}

function bar(): void {
  var_dump(foo(1, 2, 3, 4));
}

bar();

Output

vec(4){ 
  int(1)
  int(2)
  int(3)
  int(4)
}

Fallthrough

switch言論中無意的跌倒是一個常見的錯誤。黑客提供了一種抓住突破的方法,增加了一種告訴它這是有意的方法。

<?hh

namespace Hack\UserDocumentation\Types\AdvancedRules\Examples\Fallthrough;

function fallthrough(int $x): void {
  switch ($x) {
    case 1: echo "1"; break; // without the break, typechecker throws an error
    case 2: echo "2"; break;
    case 3: echo "3"; break;
    case 4: echo "4";        // but we can tell the typechecker we want it
    // FALLTHROUGH
    default: echo "5";
  }
}

fallthrough(4);

Output

45

使用// FALLTHROUGH要告訴我們的是通過故意落在typechecker。

類屬性初始化

Hack需要將類屬性在使用之前初始化為其適當(dāng)注釋類型的值。

  • 必須使用值初始化所有不可為空的靜態(tài)類屬性。
  • 默認(rèn)情況下,沒有初始值的Nullable 靜態(tài)類屬性具有null值。
  • 必須在構(gòu)造函數(shù)中初始化所有不可為空的非靜態(tài)類屬性。
  • 默認(rèn)情況下,未在構(gòu)造函數(shù)中初始化的Nullable 非靜態(tài)類屬性將具有null值。
  • 在構(gòu)造函數(shù)中初始化其屬性之前,您不能在類上調(diào)用公共或私有實(shí)例方法。
  • 在構(gòu)造函數(shù)中初始化屬性之前,您可以調(diào)用私有實(shí)例方法,只要屬性在訪問該屬性之前在該私有調(diào)用鏈的某處初始化即可。

方法繼承

父類定義一個方法,其子類覆蓋它。這很常見 Hack有一些關(guān)于重寫方法必須遵循的方法的規(guī)則。

  • 任何重寫方法的參數(shù)都必須匹配參數(shù)計數(shù)和每個參數(shù)上的類型。
  • 覆蓋方法的返回類型可能具有比其父代更具體的類型; 當(dāng)然,它們必須是兼容的(例如,arraykey在父母中,string在孩子中)。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號