【入門編】HackのGenerics入門:PHPのコードを抽象化して再利用性を高める – Hack言語 コア・静的型システムとHHVMのアーキテクチャ解析バイブル

やあ。Hackの世界へようこそ。
私はHHVMの深淵で、型チェッカーの悲鳴やJITコンパイラの吐息を聞きながらコードを磨き続けてきた者だ。

PHPの「なんとなく動く」という柔軟性は時に甘美だが、大規模なシステムを構築する際、それは技術的負債という名の時限爆弾に変わる。君が今、Hackを選んだのは賢明な選択だ。Hackは、PHPの柔軟性を持ちつつ、厳格な静的型付けによって「実行時にしか分からないバグ」を「コードを書いている最中に消し去る」言語だ。

今日は、Hackを最強の武器にするための登竜門、「ジェネリクス(Generics)」について深く掘り下げていこう。

—

1. なぜPHPの「型」では足りないのか?

PHP 7/8以降、型ヒントは随分と便利になった。しかし、こんな経験はないだろうか?

// PHPでの冗長な例
class Box {
private $item;
public function __construct($item) { $this->item = $item; }
public function getItem() { return $this->item; }
}

$box = new Box(“Apple”);
// この時、$boxの中身が何であるか、静的解析ツールは完全には把握できない。

これでは、`Box`クラスを「整数用」「文字列用」「ユーザーオブジェクト用」とコピー&ペーストして作らなければならない。非効率だし、何より「再利用性の欠如」だ。

ここで登場するのが、型を「パラメータ化」するジェネリクスだ。

—

2. ジェネリクス:型を「変数」として扱う

ジェネリクスとは、クラスや関数の定義時に「具体的な型を決めず、後で指定できるようにする」仕組みだ。

基本の書き方

Hackでは、``(TはTypeの頭文字)を使って型を抽象化する。

// Tという「箱」を用意するイメージ
class Box {
private T $item; // このクラスの内部では、Tは具体的な型として扱われる

public function __construct(T $item) {
$this->item = $item;
}

public function getItem(): T {
return $this->item;
}
}

// 使うときは、具体的に型を流し込む
$stringBox = new Box(“Hello, Hack!”);
$intBox = new Box(42);

ここがポイント:
`Box`と書いた瞬間、HHVMの型チェッカーは「このインスタンスの`getItem()`は必ず`string`を返す」と確定させる。実行時エラーを待つ必要はない。コンパイル(HHVMの解析フェーズ)で全てが明らかになるのだ。

—

3. 陥りやすい「罠」と解決策

初学者がジェネリクスで最初につまずくのは、「なんでも受け入れたい」という誘惑だ。

罠:制約のないジェネリクス

``は強力だが、`T`が「何でもいい」場合、その中身に対してメソッドを呼ぶことはできない。

class SafeBox {
public function show(T $item): void {
// エラー! Tはどんな型か不明なので、メソッドを呼ぶことはできない
// $item->toString();
}
}

解決策:型制約(`as`を使う)

「`T`は何でもいいけど、少なくともこのインターフェースを持っているものに限る」という制約を付けよう。

interface Printable {
public function toString(): string;
}

// TはPrintableを実装している必要がある、という制約
class PrintableBox {
public function show(T $item): void {
echo $item->toString(); // これなら安全に呼べる!
}
}

—

4. HSL(Hack Standard Library)との連携

HackにはHSLという、洗練された標準ライブラリがある。例えば、配列を操作する`Vec\map`関数などは、まさにジェネリクスの塊だ。

use namespace HH\Lib\Vec;

$numbers = vec[1, 2, 3];
// Vec\map が動的に型を決定する
$strings = Vec\map($numbers, (int $n) ==> (string)$n);

君が自作のロジックでジェネリクスを使いこなせれば、HSLのような「型安全で再利用性の高い」美しいコードが書けるようになる。

—

最後に:君へのアドバイス

ジェネリクスを使いこなすコツは、「まずは具体的なコードを書き、その後に抽象化する」ことだ。最初から完璧なジェネリクスを設計しようとすると、型パズルに溺れてしまう。

1. 普通の型でコードを書く。
2. 「あ、これ別の型でも同じロジックが使えるな」と気づく。
3. ``で抽象化し、型チェッカーを味方につける。

このサイクルを繰り返すだけで、君のコードの質は劇的に向上するはずだ。HHVMの静的解析エンジンは非常に優秀だ。君が型を正しく定義すれば、それは最強の「ドキュメント」であり、同時に「バグを撃退する盾」となる。

さあ、エディタを開いて、君のコードを型で武装させよう。何か詰まったら、いつでも深淵のこちら側から呼んでくれ。応援しているよ。

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