Hackの型システムを掌握する:`?`(Nullable)の連鎖を断ち切り、優雅なコードを書く極意
こんにちは。Hackの深淵を覗き込み、HHVMの熱気とともに開発を続けている皆さんに、今日は「型システムとの対話」についてお話しします。
Hackの最大の特徴である`Strict Mode`。これは単なる規約ではなく、皆さんのコードを守るための最強の防壁です。しかし、初学者が最初にぶつかる壁が「`?`(Nullable)の伝播」ではないでしょうか。
「`null`を扱うたびに`if ($x is nonnull)`を書くのが面倒……」
「コードが`null`チェックの山で埋もれていく……」
その悩み、実は設計レベルで解決できます。今日は、型チェッカーを味方につけ、`Optional`型を多用せずともクリーンなコードを維持する「Hack的思考法」を伝授します。
—
1. なぜ「Nullableの伝播」は悪なのか?
まず、なぜ`?`が広がるのが危険なのかを理解しましょう。Hackの型チェッカーは「安全でない操作」を許しません。`?T`型の変数をそのままメソッドに渡そうとすると、チェッカーは冷徹にエラーを出します。
// ダメな例:nullチェックの連鎖(いわゆる「ピラミッドコード」)
function processUser(?User $user): void {
if ($user !== null) {
$profile = $user->getProfile();
if ($profile !== null) {
echo $profile->getName();
}
}
}
このコードは、深く潜れば潜るほど可読性が落ち、メンテナンスの悪夢を引き起こします。これが「Nullableの伝播」です。これを防ぐには、「そもそもnullを発生させない境界線を引く」ことが重要になります。
—
2. 伝播を止めるための3つの武器
① 「空オブジェクト(Null Object)」パターンの活用
`null`を返すのではなく、「何もしない」という状態を持つオブジェクトを返します。これにより、呼び出し側は`null`チェックから解放されます。
interface UserInterface {
public function getName(): string;
}
class RealUser implements UserInterface {
public function getName(): string { return “Alice”; }
}
class GuestUser implements UserInterface {
// nullを返さず、デフォルト値を返す
public function getName(): string { return “Guest”; }
}
このように設計すれば、型チェッカーは`UserInterface`型のオブジェクトに対して安心して`getName()`を呼び出せます。
② `Shapes`と`idx`の賢い付き合い方
Hackの`shape`は強力ですが、アクセス時に`null`になりがちです。ここで`idx`関数を闇雲に使うのではなく、「型定義の段階で必須項目を分ける」のがプロの流儀です。
type TUser = shape(
‘id’ => int,
‘name’ => string,
?’email’ => string, // 必須ではないものだけをNullableにする
);
すべてをNullableにせず、必要な情報だけを厳格に定義することで、無駄な`null`チェックを排除できます。
③ 早期リターン(ガード節)による「型昇格」
Hackの型チェッカーは、`if`文によるチェックを記憶します。これを活用して、関数内の早い段階で`null`を排除し、以降のコードを「純粋な型」として扱わせるのが定石です。
function updateName(?User $user): void {
// ガード節:ここでnullを排除
if ($user is null) {
return;
}
// ここから先、$userは非NullableのUser型として推論される!
$user->setName(“New Name”);
}
この「型昇格(Type Promotion)」こそが、HackをHackたらしめる強力な機能です。
—
3. 陥りやすい罠:`??`(Null Coalesce)の依存
初学者がやりがちなのが、何でもかんでも `??` でデフォルト値を埋めてしまうこと。
// 危険な例
$name = $user?->getName() ?? “Unknown”;
一見スマートですが、これを行うと「なぜ`null`になる可能性があるのか」というドメイン上の事実が隠蔽されてしまいます。`null`は「値がない」という重要な情報です。 その情報を隠すのではなく、処理の境界線で適切に型を確定させるのが、Hackの真髄です。
—
まとめ:型チェッカーと「対話」しよう
Hackの型チェッカーは、皆さんのコードを邪魔する敵ではありません。あなたの設計が「曖昧であること」を指摘してくれる、最も親切なコードレビューアーです。
1. Nullableの範囲を最小化する(境界線を作る)
2. Null Objectパターンで例外的な状態をカプセル化する
3. ガード節で型を昇格させ、ロジックをシンプルにする
ここをクリアすれば、あなたの書くHackコードは、堅牢で、かつ驚くほど読みやすいものへと進化するはずです。
「型システムを制御下に置く」。それができれば、大規模なHHVMプロジェクトも怖くありません。さあ、次はどんなコードを書きましょうか? 応援していますよ!