ハロー。Hackの世界へようこそ。HHVMの深淵を覗き込み、静的型システムという名の「規律」を味方につけようとしている君を歓迎するよ。
多くの開発者がHackを触り始めた時、最初にぶつかる壁が「Nullableの伝播」だ。`?int` や `?string` という型が、まるでウイルスのようにコード全体へ広がっていき、いたるところで `null check` を強制される。
「なぜこんなに厳しいのか?」と嘆きたくなるかもしれないけれど、これは君のコードをバグという名の怪物から守るための防波堤なんだ。今日は、その防波堤をどう制御し、コードの健全性を保つか、その核心を話そう。
—
1. なぜ「Nullable」は伝播するのか?
まず、心に留めておいてほしい。Hackの型チェッカーは「安全でない操作は決して許さない」という哲学で動いている。
例えば、ある関数が `?int` を返すとき、それをそのまま別の関数の引数(`int` を期待している場所)に渡せば、即座に型エラーだ。型チェッカーは「もしその値が `null` だったら?」という問いを常に投げかけてくる。
よくある「汚染」の例
<<__EntryPoint>>
function main(): void {
$data = getData(); // ここで ?int が返ってくる
// 型エラー:?int は int として扱えない
processData($data);
}
function getData(): ?int { / …何らかの処理… / return null; }
function processData(int $val): void { / …処理… / }
ここで多くの初心者がやってしまうのが、「とりあえずどこでも `?` をつけて Nullable にしてしまう」という逃げ道だ。これは絶対にやめてほしい。Nullableが伝播すればするほど、君のコードは実行時の不確実性に支配され、型システムの恩恵がすべて消えてしまうからね。
—
2. 型エラーを局所化する「設計術」
Nullableの伝播を止めるには、「境界線(Boundary)」を引くのが鉄則だ。HHVMの型チェッカーを味方につけるための3つのステップを紹介するよ。
ステップ1:早期リターンで「安心」を確保する
最もシンプルで最強の方法は、値を取得した直後に `null` かどうかを判定し、処理を分岐させることだ。
function execute(): void {
$data = getData();
// 早期リターンで null の可能性を排除する
if ($data === null) {
return; // ここで ?int の呪縛から解放される
}
// ここからは型チェッカーが $data を int として認識してくれる
processData($data);
}
ステップ2:デフォルト値で「型」を固定する
もし `null` が「単に値がないだけ」なら、あえて `null` を持ち歩かず、デフォルト値に置換してしまおう。
function getSafeData(): int {
$data = getData();
// Nullable をその場で消去する
return $data ?? 0;
}
この `??` (Null合体演算子)は、単なる糖衣構文じゃない。「Nullableという不確実な未来を、具体的な型という確定した現在に変える」ための魔法の杖だ。
ステップ3:Maybeモナド的思考で境界を隠蔽する
複雑なロジックであれば、Nullableな値を直接扱うのではなく、それを安全に処理する「コンテナ」的な関数を用意するのも手だ。
—
3. なぜこの設計が重要なの?(HHVMの視点)
HHVMのJITコンパイラは、コードの型が確定していればいるほど、爆速で最適化をかける。`?int` のように型が曖昧だと、実行時に「これはnullか? それとも整数か?」をチェックするオーバーヘッドが生まれる。
つまり、型エラーを局所化して型を確定させることは、コードの安全性を高めるだけでなく、アプリケーションのパフォーマンスを物理的に引き上げることと同義なんだ。
—
まとめ:君が守るべき3つの原則
1. 「?」を安易に伝播させない:関数の戻り値に `?` をつけるなら、その理由を明確にすること。
2. 早期リターンを恐れない:コードが長くなっても、型が確定する領域を分ける方が、後々のデバッグコストは圧倒的に低い。
3. 境界線で型を変換する:外部(DBやAPI)から来る `?` は、アプリケーションの入り口で、必ず `int` や `string` のような「確実な型」に変換して内部へ通そう。
ここをクリアすれば、君はもうHackの初心者じゃない。型チェッカーと「対話」しながら、意図した通りの頑健なシステムを組み上げられるようになるはずだ。
次は、`Shapes` や `Type Alias` を使って、さらに厳格な型定義の世界へ飛び込んでみようか。Hackの旅はまだ始まったばかりだよ。質問があればいつでも聞いてくれ。応援しているよ!