hack集合:hack arrays

2018-10-26 11:41 更新

hack提供额外的“阵列状”的类型:dict,vec,和keyset; 我们预计这些将最终替换收集对象,并且将被建议,一旦Hack标准库离开'预览'状态,它们将被使用 。

类型

  • vec<T>是类型项目的可索引和可​​移动容器T; 它是作为替换的VectorImmVectorConstVector
  • dict<Tk as arraykey, Tv>是可转位和可键合的可移动容器的类型的项目Tv; 这是作为替换的MapImmMapConstMap。Tk必须是一个arraykey,即string或int键。
  • keyset<T as arraykey>是一个可索引和键入的可移动容器的唯一项目类型T; 这是作为替换的SetImmSetConstSet。它只能包含arraykey值,即string或int。

所有这些类型都保留插入顺序。

创建Hack数组

文字用[]语法创建:

<?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还提供以下转换功能:

  • 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标准库提供

完整的API参考是自动生成的,但我们强烈建议您先阅读 README

与hack集合相比

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

  • Hack集合通过引用隐式传递
  • Hack数组通过值隐含地传递,具有类似写入的行为
  • Hack数组没有方法,需要库函数
  • 没有必要Const或Imm变体的Hack数组

引用和写时复制语义之间的区别如下所示:

<?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数组相比

  • Hack数组不会将int类型的字符串键隐式转换为int
  • 当未定义的索引被访问时,hack数组会显示异常,而不是返回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


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号