hack集合:Iterating

2018-10-25 11:49 更新

集合通過(guò)迭代(Iterating)foreach。

<?hh

namespace Hack\UserDocumentation\Collections\Iterating\Examples\FEach;

function run(): void {
  $vec = Vector {'A', 'B', 'C'};
  $map = Map {'A' => 1, 'B' => 2};
  $set = Set {800, 900, 1000};
  $pair = Pair {'A', 'B'};

  foreach ($vec as $val) {
    var_dump($val);
  }

  foreach ($map as $key => $val) {
    var_dump($key);
    var_dump($val);
  }

  foreach ($set as $val) {
    var_dump($val);
  }

  foreach ($pair as $key => $val) {
    var_dump($key);
    var_dump($val);
  }
}

run();

Output

string(1) "A"
string(1) "B"
string(1) "C"
string(1) "A"
int(1)
string(1) "B"
int(2)
int(800)
int(900)
int(1000)
int(0)
string(1) "A"
int(1)
string(1) "B"

注意事項(xiàng)

當(dāng)使用它foreach來(lái)迭代集合時(shí),有幾點(diǎn)值得注意的注意事項(xiàng)。

修改集合

不允許從集合添加或刪除項(xiàng)目,如果嘗試,將導(dǎo)致一個(gè)InvalidOperationException。

<?hh

namespace Hack\UserDocumentation\Collections\Iterating\Examples\Modifying;

function run(): void {
  $vec = Vector {'A', 'B', 'C'};

  try {
    foreach ($vec as $val) {
      if ($val === 'B') {
        // This will actually be allowed, but the next time through the loop
        // the InvalidOperationException will be thrown.
        $vec[] = 'D';
      }
      var_dump($vec);
      var_dump($val);
    }
  } catch (\InvalidOperationException $ex) {
    var_dump($ex->getMessage());
  }

  $set = Set {100, 200, 300};

  try {
    foreach ($set as $val) {
      if ($val === 300) {
        // This will actually be allowed, and even though this is the last
        // element in the set, we actually do the check in the foreach again so
        // the InvalidOperationException will be thrown.
        $set->remove(300);
      }
      var_dump($set);
      var_dump($val);
    }
  } catch (\InvalidOperationException $ex) {
    var_dump($ex->getMessage());
  }
}

run();

Output

object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
string(1) "A"
object(HH\Vector)#1 (4) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
  [3]=>
  string(1) "D"
}
string(1) "B"
string(40) "Collection was modified during iteration"
object(HH\Set)#3 (3) {
  int(100)
  int(200)
  int(300)
}
int(100)
object(HH\Set)#3 (3) {
  int(100)
  int(200)
  int(300)
}
int(200)
object(HH\Set)#3 (2) {
  int(100)
  int(200)
}
int(300)
string(40) "Collection was modified during iteration"

請(qǐng)注意,在該示例中,實(shí)際的添加或刪除將生效,但是當(dāng)我們回到循環(huán)迭代檢查時(shí)將拋出異常。

參考

您不能通過(guò)foreach引用作為集合。

foreach ($vec as &$val)

這將導(dǎo)致致命的錯(cuò)誤,甚至不是例外。

有一種模擬這種行為的方法。

<?hh

namespace Hack\UserDocumentation\Collections\Iterating\Examples\Reference;

function run(): void {
  $arr = array ('A', 'B', 'C');
  // if $arr was a Vector instead, we would get a
  // Fatal error: Collection elements cannot be taken by reference
  var_dump($arr);
  foreach ($arr as &$val) {
    var_dump($val);
    if ($val === 'B') {
      $val = 'D';
    }
    var_dump($arr);
  }

  // How to mimic the above
  $vec = Vector {'A', 'B', 'C'};
  var_dump($vec);
  foreach ($vec as $key => $val) {
    var_dump($val);
    if ($val === 'B') {
      $vec[$key] = 'D';
    }
    var_dump($vec);
  }
}

run();

Output

array(3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
string(1) "A"
array(3) {
  [0]=>
  &string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
string(1) "B"
array(3) {
  [0]=>
  string(1) "A"
  [1]=>
  &string(1) "D"
  [2]=>
  string(1) "C"
}
string(1) "C"
array(3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "D"
  [2]=>
  &string(1) "C"
}
object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
string(1) "A"
object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
string(1) "B"
object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "D"
  [2]=>
  string(1) "C"
}
string(1) "C"
object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "D"
  [2]=>
  string(1) "C"
}

基本上,您明確拉出集合的鍵/值對(duì),然后顯式修改鍵的值。

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)