【実務・中級編】PHPの配列からHackのVector/Mapへ:型安全なコレクションへの段階的移行戦略 – Hack言語 コア・静的型システムとHHVMのアーキテクチャ解析バイブル

PHPの「何でも入る配列」を捨て去れ:Hackにおける型安全なコレクションへの静的変革

我々がHHVMを設計し、Hackという言語を世に送り出した最大の理由は明確だ。「動的型付けの曖昧さが引き起こす、実行時の予測不能な爆発」を、コンパイル時にすべて殲滅するためだ。

PHPの連想配列(`array`)は、ある意味で「最強の万能ナイフ」だが、その実態は型安全性を放棄した「ゴミ箱」に過ぎない。`Map`や`Vector`、あるいは`keyset`への移行は、単なるリファクタリングではない。アプリケーションの実行時エラーをコンパイル時の警告へ変換する、極めて戦略的な投資である。

今日は、PHPの腐った配列をHackの純粋なコレクションへと昇華させるための、アーキテクトとしての流儀を伝授する。

—

1. なぜ「連想配列」が癌なのか:メモリと型安全性の罠

PHPの配列は、ハッシュテーブルと連結リストが複雑に絡み合ったメモリ上の怪物だ。型情報が欠落しているため、HHVMのJITコンパイラは「いつ型が変わるか分からない」という前提でコードを最適化しなければならない。

Hackの`Vector`や`Map`は違う。これらはメモリレイアウトが最適化されており、型が固定されているため、HHVMがよりアグレッシブな型推論と最適化(Type Specialization)を適用できる。

アンチパターン:PHPスタイルの「何でも入る箱」

// 危険:型が保証されず、実行時まで内容が不明
function process_data(array $data): void {
// $data[‘user’] が存在するか? intかstringか?
// 開発者は祈るしかない
echo $data[‘user’][‘name’];
}

—

2. 段階的移行の極意:`shape`という「中継地」を使いこなせ

いきなり全ての配列を`Map`に変換するのは無謀だ。まずは`shape`を使って「構造の強制」から始めろ。

`shape`は、ハッシュテーブルの柔軟性を保ちつつ、コンパイル時にキーと値の型を静的に固定する。これは配列からコレクションへの架け橋となる強力なツールだ。

改善された実装例

// User情報を定義するShape
type User = shape(
‘id’ => int,
‘username’ => string,
‘email’ => ?string, // null許容の明示
);

// 型安全にコレクションを扱う
function process_user(Vector $users): void {
foreach ($users as $user) {
// コンパイラが $user[‘id’] が int であることを保証する
echo “ID: ” . $user[‘id’];
}
}

—

3. `Vector`, `Map`, `keyset` の適材適所

移行の際、闇雲に`Map`を使えばいいというものではない。Hackのコレクションには明確な設計思想がある。

  • `Vector`: インデックスアクセスが主。`array_push`や`array_pop`の代替。要素の順序が重要で、高速な反復処理を行う場合に最適。
  • `Map`: キーと値のペア。PHPの連想配列の正当な後継者。ただし、キーが複雑でないなら`dict`も検討せよ。
  • `keyset`: 一意な値の集合。`in_array()`で悩む日々は終わりだ。`contains`メソッドによるO(1)の検索性能は、実務のパフォーマンスを劇的に改善する。

実務で使える美しいコード:APIレスポンスの正規化

use namespace HH\Lib\Vec;

final class UserRegistry {
// dictはイミュータブルで高速なコレクション
private dict $users = dict[];

public function add(User $user): void {
$this->users[$user[‘id’]] = $user;
}

// HSL(Hack Standard Library)を活用した美しいフィルタリング
public function getActiveUserIds(): keyset {
return keyset(
Vec\map($this->users, ($user) ==> $user[‘id’])
);
}
}

—

4. パフォーマンス上の注意点:コピーと参照

PHPの配列は「書き込み時コピー(Copy-on-Write)」で動作するが、Hackのコレクションは型安全性を担保するために、イミュータブルな設計を推奨している。

  • 無駄なコピーを避ける: 大量のデータを扱う際は、`Vector`を何度も生成せず、HSLの`Vec\map`や`Vec\filter`を使い、イテレータ的に処理を繋げ。
  • Dict vs Map: ほとんどの場合、`dict`で十分だ。`dict`はHHVMの内部構造において、最も効率的にメモリ配置される。`Map`を使うのは、実行時に要素の追加・削除が頻繁に発生する場合のみに限定せよ。

—

5. チーフアーキテクトからの助言

移行作業において最も重要なのは、「型定義を妥協しないこと」だ。

`mixed`型を多用して「型チェックを潜り抜ける」のは、死への近道だ。最初は`array`として定義し、徐々に`shape`へ、最終的には`class`や`readonly class`へと昇華させる。この段階を踏むことで、バグはコードを書いている最中に蒸発する。

Hackのパワーを解放せよ。あなたのコードは、もっと速く、もっと堅牢になれるはずだ。

もし、コンパイルエラーに悩まされているなら、それはコードが間違っているのではなく、あなたの設計がまだPHPの古い慣習に縛られている証拠だ。 型チェッカーの警告は、敵ではなく、あなたのコードを救うための「未来からの警告」だと受け止めろ。

さあ、エディタを開け。`array`という文字を、あなたのプロジェクトから一掃する時間だ。

タイトルとURLをコピーしました