hack集合:hack arrays

2018-10-26 11:41 更新

hack提供額外的“陣列狀”的類型:dict,vec,和keyset; 我們預(yù)計這些將最終替換收集對象,并且將被建議,一旦Hack標(biāo)準(zhǔn)庫離開'預(yù)覽'狀態(tài),它們將被使用 。

類型

  • vec<T>是類型項目的可索引和可??移動容器T; 它是作為替換的Vector,ImmVectorConstVector
  • dict<Tk as arraykey, Tv>是可轉(zhuǎn)位和可鍵合的可移動容器的類型的項目Tv; 這是作為替換的MapImmMapConstMap。Tk必須是一個arraykey,即string或int鍵。
  • keyset<T as arraykey>是一個可索引和鍵入的可移動容器的唯一項目類型T; 這是作為替換的Set,ImmSetConstSet。它只能包含arraykey值,即string或int。

所有這些類型都保留插入順序。

創(chuàng)建Hack數(shù)組

文字用[]語法創(chuàng)建:

<?hh

namespace Hack\UserDocumentation\Collections\HackArrays\Examples\Literals;

function main(): void {
  var_dump(vec[1, 2, 3, 1]);
  var_dump(dict['a' => ord('a'), 'b' => ord('b'), 'c' => ord('c')]);
  var_dump(keyset[1, 2, 3, 1]);
}

main();

Output

vec(4) {
  int(1)
  int(2)
  int(3)
  int(1)
}
dict(3) {
  ["a"]=>
  int(97)
  ["b"]=>
  int(98)
  ["c"]=>
  int(99)
}
keyset(3) {
  int(1)
  int(2)
  int(3)
}

此外,Hack還提供以下轉(zhuǎn)換功能:

  • vec<Tv>(Traversable<Tv>): vec<Tv>
  • dict<Tk as arraykey, Tv>(KeyedTraversable<Tk, Tv>): dict<Tk, Tv>
  • keyset<Tv as arraykey>(Traversable<Tv>): keyset<Tv>
<?hh

namespace Hack\UserDocumentation\Collections\HackArrays\Examples\Conversions;

function main(): void {
  var_dump(vec(Vector { 1, 2, 3, 1 }));
  var_dump(dict(Map {'a' => ord('a'), 'b' => ord('b'), 'c' => ord('c') }));
  var_dump(keyset(Vector {1, 2, 3, 1 }));
  var_dump(keyset(Set {1, 2, 3, 1 }));
}

main();

Output

vec(4) {
  int(1)
  int(2)
  int(3)
  int(1)
}
dict(3) {
  ["a"]=>
  int(97)
  ["b"]=>
  int(98)
  ["c"]=>
  int(99)
}
keyset(3) {
  int(1)
  int(2)
  int(3)
}
keyset(3) {
  int(1)
  int(2)
  int(3)
}

Library功能

由于Hack Arrays不是對象,它們沒有方法。Library支持通過Hack標(biāo)準(zhǔn)庫提供。

完整的API參考是自動生成的,但我們強(qiáng)烈建議您先閱讀 README

與hack集合相比

hack集合(Vector,Map,Set,...)都是對象; hack陣列(vec,dict,keyset)是值。主要影響是:

  • Hack集合通過引用隱式傳遞
  • Hack數(shù)組通過值隱含地傳遞,具有類似寫入的行為
  • Hack數(shù)組沒有方法,需要庫函數(shù)
  • 沒有必要Const或Imm變體的Hack數(shù)組

引用和寫時復(fù)制語義之間的區(qū)別如下所示:

<?hh

namespace Hack\UserDocumentation\Collections\HackArrays\Examples\RefVsCow;

function do_stuff($container) {
  $container[] = 456;
  return $container;
}

function main(): void {
    $a = Vector { 123 };
    $b = do_stuff($a);
    $x = vec[123];
    $y = do_stuff($x);

    var_dump([
        array(
            'in' => $a,
            'out' => $b,
            'mutated' => $a == $b,
        ),
        array(
            'in' => $x,
            'out' => $y,
            'mutated' => $x == $y,
        ),
    ]);
}

main();

Output

array(2) {
  [0]=>
  array(3) {
    ["in"]=>
    object(HH\Vector)#1 (2) {
      [0]=>
      int(123)
      [1]=>
      int(456)
    }
    ["out"]=>
    object(HH\Vector)#1 (2) {
      [0]=>
      int(123)
      [1]=>
      int(456)
    }
    ["mutated"]=>
    bool(true)
  }
  [1]=>
  array(3) {
    ["in"]=>
    vec(1) {
      int(123)
    }
    ["out"]=>
    vec(2) {
      int(123)
      int(456)
    }
    ["mutated"]=>
    bool(false)
  }
}

與PHP數(shù)組相比

  • Hack數(shù)組不會將int類型的字符串鍵隱式轉(zhuǎn)換為int
  • 當(dāng)未定義的索引被訪問時,hack數(shù)組會顯示異常,而不是返回null。

  • 不能包含引用

禁止引用的證明如下:

<?hh

namespace Hack\UserDocumentation\Collections\HackArrays\Examples\CanNotContainReferences;

function foo(int &$foo) {
  $foo = 346;
}

$y = vec[1,2,3];
foo($y[2]);
var_dump($y);

Output

Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Vecs cannot contain references' in /Users/fredemmott/code/user-documentation/guides/hack/23-collections/11-hack-arrays-examples/can-not-contain-references.php:10
Stack trace:
#0 {main}
Examples


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號