list型
静的解析ツールに実装された独自の型。基本的にはPHPDocに書くことで用いる。 list($a, $b) = f() のような形式で返り値を受け取るパターン(タプル)とは使用箇所が異なる リストとは、以下のような連番の要素を持つ配列を指す
code:php
// 値が追加されることもできる
$list[] = 4;
code:php
$assoc = [
11 => 1,
30000 => 2,
5656 => 6,
];
どちらもarray<int, int>になってしまう
list<string>やlist<int>のようにジェネリクスを組み合わせて書くことができる。 配列の中にどんな要素が入るかを制約できる
どんな種類の値でも入りうる場合はmixed型を組合せてlist<mixed>とする 以前のバージョンのPHPStan(1.8以下)のlist<T>はarray<int, T>のエイリアスなので注意
上記のキーがintの連想配列とリストを型レベルで区別できない
フルサポートするわけではなく互換性のために最低限の検査だけしていた状態
list<string>で['a', 'b']だけでなく[2 => 'x', 5 => 'y']も通してしまう
空ではないリストをnon-empty-listとして区別できる
@return list<int>としたときreturn [];と返しても問題ないが、non-empty-listで制限できる
list型の値が空でないことが保証できると以下のような場合に役立つ
code:php
/**
* @phpstan-param non-empty-list<int> $ids
* @return non-empty-array<int, array{name:string}>
*/
function search_ids(array $ids): array {
foreach ($ids as $id) {
$val = search($id);
}
return $result;
}
foreach が最低一回実行される
$result が未定義にならず、空ではない配列を返す
array_is_list()の定義は以下のPHP関数と等価だとされている
code:php
function array_is_list(array $array): bool {
$expectedKey = 0;
foreach ($array as $i => $_) {
if ($i !== $expectedKey) { return false; }
$expectedKey++;
}
return true;
}
上記 RFCより抜粋
ただしビルトイン関数版はPHPの内部表現を使うようになっているので効率化されている
コンピュータサイエンスで「リスト」というと連結リストのようなデータ構造を指すことがあるが、PHPではあくまで配列である。 真の配列であれば高速に結果を返すように最適化されている
内部的に連想配列化されていても上記PHPコードと同等の判定があるので心配は不要
array<T>をlist<T>に変換する方法
array_values()は配列の要素だけを抽出する関数です
code:php
結果は連想配列ではなく真の配列(list型)になることを保証できます
マニュアル
PHPStan 1.9ではbleedingEdgeを有効化しないと0から始まる連番かどうかの検査はできない
以前はマニュアルに記載はなかったがarray<int,T>扱いとしてが最低限の実装がされていた