やあ。Hackの世界へようこそ。私はHHVMのコアを長年見守ってきたアーキテクトだ。
君がいま触れている「Hack」という言語は、単なるPHPの進化系ではない。静的型付けの厳格さと、JITコンパイラによる圧倒的な実行速度を両立させた、極めてエッジの効いた言語だ。
今日は、Hackの真髄である「Strict Mode」へ至るための、最も重要かつ挑戦的なテーマ――『Any型(非型付け)からの脱却』について語ろう。
—
なぜ「Any型」はHackの敵なのか?
Hackには、かつてのPHPの自由さを残した`Partial`モードと、厳格な型安全を保証する`Strict`モードがある。
`Partial`モードで頻出する「型推論が効かず、何を代入してもエラーにならない状態(=Any的挙動)」は、一見便利に見えるよね。しかし、それは「地雷を隠し持った爆弾」と同じだ。実行時に予期せぬ型が混入し、プロセスのクラッシュを招く。
我々が目指すのは、コンパイル時(型チェック時)にすべてのエラーを潰し、HHVMに「このコードは100%安全だ」と確信させること。それがパフォーマンスと堅牢性を最大化する唯一の道なんだ。
—
ステップ1:Anyの正体を暴く
まずは、君のコードに潜む「型なし」の典型例を見てみよう。
// Partialモード(ファイルの先頭に <
function process_data($input) { // ここ! $input の型が不明(Any)
return $input->value 2; // 実行するまで $input に何が入るかわからない
}
このコードでは、HHVMは「`$input`はオブジェクトなのか?配列なのか?あるいは単なる整数なのか?」を推測できない。これが、ランタイムでの悲劇の始まりだ。
—
ステップ2:段階的リファクタリングの鉄則
一気に全てを直そうとすると、型エラーの嵐に溺れてしまう。以下の手順で進めるのが、経験豊富なエンジニアのやり方だよ。
1. Shapeで構造を固定する
連想配列を使っている箇所を、`shape`型に置き換えよう。これが最も効果的で、Hackらしい解決策だ。
// 改善前:連想配列(中身が不明)
function get_user_name(dict
return $user[‘name’]; // 危険! ‘name’キーが存在するか確証がない
}
// 改善後:Shapeで構造を定義
type User = shape(‘id’ => int, ‘name’ => string);
function get_user_name(User $user): string {
return $user[‘name’]; // 安全!コンパイラが ‘name’ の存在と型を保証する
}
2. 「mixed」を撲滅する
`mixed`はHackにおける「Any」の象徴だ。まずは `mixed` を使っている箇所を、具体的な型(`string`, `int`, `vec
function process(mixed $data): void {
// is演算子で型を確定させるのがHack流
if ($data is int) {
echo $data + 10; // ここでは $data は確実に int
} else if ($data is string) {
echo strlen($data); // ここでは $data は確実に string
}
}
—
陥りやすい罠:「型エラー」との付き合い方
Strict Modeに移行しようとすると、必ず「そんな型は定義されていない」や「型の不一致」というエラーが出る。初心者ほどここで挫折するが、これは「エラー」ではなく「HHVMからのアドバイス」だと思ってほしい。
- 「`?` (Nullable) を忘れるな」: 値が空かもしれない場所には必ず `?` をつけること。これをサボると、NULLポインタ例外でシステムが止まる。
- 「コレクション型を明示せよ」: `vec` や `dict` を使うときは、必ず中身の型を指定しよう。`vec
` と書くだけで、HHVMの最適化は劇的に向上する。
—
さあ、Strictのその先へ
ここまでクリアできれば、君のコードはもう「ただ動くコード」ではない。「HHVMが最適化を極限まで引き出せる、堅牢なプロダクト」に生まれ変わっているはずだ。
Hackの型システムは、君の敵ではない。君のロジックが論理的に正しいことを証明してくれる、最強のパートナーだ。
「型を書くのが面倒」という感情を捨て、「型を書くことで、未来の自分をバグから守る」というエンジニアとしての矜持を持つこと。そうすれば、君は間違いなく世界トップクラスのHackエンジニアへの道を歩み始めているよ。
さて、次は君のプロジェクトで、最初の一行に `<<__Strict>>` を記述してみよう。そこから全てが始まる。応援しているよ!