【入門編】Hackの『Tuple』型と『List』型の使い分け:固定長と可変長の型安全な管理 – Hack言語 コア・静的型システムとHHVMのアーキテクチャ解析バイブル

こんにちは!Hack言語の世界へようこそ。チーフアーキテクトの私です。

他のプログラミング言語、例えばPHPやJavaScriptなどからHackの世界に飛び込んできたとき、多くの開発者が最初に感動し、そして少しだけ戸惑うのが「厳格な静的型システム(Strict Mode)」です。型チェッカーが私たちのコードを隅々まで見張り、実行時エラーの芽を片っ端から摘み取ってくれるあの感覚は、慣れると本当に手放せなくなりますよね。

さて、今回はそんなHackの型システムの中でも、データの「集まり」を扱うときに必ず直面する「Tuple(タプル)」型と「List(ベクター/コレクション)」型の使い分けについて、徹底的に深掘りしていきましょう。

「要素数が決まっているデータ」と「可変長のデータ」、それぞれにどの型構造を選ぶのがベストなのか?ここをクリアすれば、あなたのHackコードは一気に洗練され、型安全の要塞と化しますよ。それでは、一緒に見ていきましょう!

—

1. Tuple型とList型って、そもそも何が違うの?

まずは、頭の中でイメージしやすいように、この2つの違いを整理しておきましょう。

  • Tuple(タプル)型:【固定長・異種混合】
  • イメージ:「ロッカーの番号が決まっていて、中身の指定席がある状態」
  • 特徴:要素数がガチガチに固定されており、何番目に何型が入るかが厳密に決まっています。中身のデータ型がバラバラでもOKです。
  • List(リスト / ベクター)型:【可変長・同種混合】
  • イメージ:「買い物のメモ用紙。上から順に同じ種類のアイテムをいくらでも書き足せる状態」
  • 特徴:要素数が伸縮します(増えたり減ったりする)。ただし、基本的には「すべて同じ型(同種)」のデータを扱います。

【Tupleのイメージ】 (固定長・型バラバラ)
[ 0番目: string ] [ 1番目: int ] [ 2番目: bool ]
“User-001” 42 true

【Listのイメージ】 (可変長・型統一)
[ int ] -> [ int ] -> [ int ] -> …
10 20 30

この違い、なんとなく掴めましたよね?それでは、それぞれの具体的な使い方と、HHVMの裏側でどう扱われているのかを覗いてみましょう。

—

2. Tuple型:型安全な「構造体」のミニマム版

まずはTuple型です。HackにおけるTupleは `(T1, T2, …)` のように書きます。

例えば、「ユーザーのID(文字列)、年齢(整数)、アクティブ状態(真偽値)」をセットで関数から返したいとしましょう。わざわざ専用のクラスを定義するほどでもないな、という時にTupleは最高の相棒になります。

基本的なコードと意味

<<__Strict>>
namespace HackArchitect\Guide;

// ユーザー情報(ID, 年齢, アクティブフラグ)を返す関数
function get_user_profile(): (string, int, bool) {
// 順番と型が厳密に一致している必要があります
return tuple(“DEV-999”, 28, true);
}

function main(): void {
// タプルを受け取る
$profile = get_user_profile();

// 要素へのアクセス(0始まりのインデックス)
$userId = $profile[0]; // string型として推論される
$age = $profile[1]; // int型として推論される

// もしここで間違った型を期待すると、型チェッカーが即座に怒ってくれます!
// $invalid = $profile[0] + 1; // エラー: stringとintは足せません

echo “User: {$userId}, Age: {$age}\n”;
}

ここで陥りやすい罠:インデックスの魔力

初心者がやりがちなのが、Tupleの要素をマジックナンバー(`0`, `1`, `2`…)のままであちこちで使い回してしまうことです。「あれ?`[1]`って年齢だっけ、それともスコアだっけ?」となってコードが読めなくなります。

Tupleはあくまで「スコープが狭い関数間の受け渡し」や「一時的なペアリング」に留めるのが、美しいHackコードを書くコツですよ。要素が増えてきたら、迷わず `class` や `record` を定義しましょう。

—

3. List型(ベクター):伸び縮みするデータの安全な管理

次に、要素数が変わるデータの代表格である「List(ベクター)」を見ていきましょう。Hackでは通常、`vec` という型を使用します(旧来の `array` 型の曖昧さから脱却し、HHVMで爆速に動作するように最適化された強力なコレクションです)。

基本的なコードと意味

<<__Strict>>
namespace HackArchitect\Guide;

function process_scores(vec $scores): int {
$total = 0;
// 可変長のデータを安全にループ処理
foreach ($scores as $score) {
$total += $score;
}
return $total;
}

function main_list(): void {
// 整数のみを格納する可変長リスト
// 要素数は後から追加(Vec\pushなど)で増減可能
$myScores = vec[85, 90, 78, 92];

$sum = process_scores($myScores);
echo “Total Score: {$sum}\n”;

// 型違反の例:
// $myScores[] = “90”; // エラー!vecにstringは入れられません
}

HHVMの裏側:なぜ `vec` なのか?

少しだけアーキテクチャの話をしましょう。PHPの従来の `array` は、ハッシュマップ(連想配列)でありながらインデックス配列としても振る舞うという、メモリ効率の悪い「万能すぎる構造」でした。

しかし、Hackの `vec` は、HHVMのエンジン内部で「連続したメモリ領域に配置された純粋なインデックス配列」として表現されます。これにより、C言語の配列並みの高速なランダムアクセスと、キャッシュヒット率の向上を実現しています。だからこそ、型チェッカーが「このベクターには `int` しか入らない」と保証することが、パフォーマンス向上に直結するのです。

—

4. どっちを選ぶべき?判断に迷ったときの指針

実際の開発現場で、「ここはTupleにすべきか?それとも `vec` にすべきか?」と迷ったら、以下の2つの質問を自分に投げかけてみてください。

1. 「要素の数は、実行中やビジネスロジックの中で増減しますか?」

  • はい $\rightarrow$ 迷わず `vec`(List) です。
  • いいえ(決まった構造・ペア) $\rightarrow$ 次の質問へ。

2. 「要素の型はすべて同じですか、それとも位置によって異なりますか?」

  • すべて同じ $\rightarrow$ 要素数が固定であっても、場合によっては `vec`(または固定長を保証したい場合は専用の構造)を検討しますが、単なるリストなら `vec`。
  • 位置によって型が違う(例: 0番目は文字列、1番目は数値) $\rightarrow$ Tuple の独壇場です!

—

まとめ:型安全なデータ構造でHHVMを唸らせよう

今回は、Hack言語における固定長の「Tuple」と可変長の「List(`vec`)」の使い分けについて解説しました。

  • Tuple `(T1, T2)`: 要素数固定・型混在OK。構造体の軽量版として、密なデータのやり取りに。
  • List `vec`: 要素数可変・型統一。HHVMの高速なメモリ管理の恩恵を受けながら、安全にコレクションを操作。

この2つを適切に使い分けられるようになると、あなたの書くHackコードの堅牢性は劇的に跳ね上がります。型チェッカーはあなたを縛る鎖ではなく、最高のエキサイティングな開発体験をもたらす相棒です。

ここをクリアできれば、Hackの基本はもうバッチリマスターできましたよ!自信を持って次のステップへ進んでくださいね。それでは、また次回のアーキテクチャ解説でお会いしましょう!

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