Zigコースのまとめ

Basis
最終更新: タグ: Zig

Project Hematite の Zig パートを終えた — Zig が目的地だからではなく、Zig が抽象化を取り払い、コンピューターが実際にどう動くかを見せてくれるからだ。このチェックポイントでは一歩引いて、各ピースをつなぎ合わせる。

コースで扱った内容

Zigコースでは5つの相互に関連した領域で知識を積み上げた。

データの表現

まず、あらゆる言語が最終的にコンパイルして落とし込むプリミティブ型から始めた:

  • ブール値(boolean)true または false という1ビットの情報、そしてそれを生み出す比較演算子と論理演算子。
  • 整数(integer) — 固定幅の符号付き・符号なし値(i32u64 など)。幅が値の範囲を決め、オーバーフロー動作は暗黙ではなく明示的であり、型の選択は正確さとメモリ使用の両方に影響する。
  • 浮動小数点(float) — IEEE 754 表現、浮動小数点演算が初学者を驚かせる理由、そして f32f64 をどちらを選ぶか。
  • 文字列(string) — Zig ではファーストクラスのプリミティブではなく、バイトのスライスだ。文字列を直接扱うことで、文字エンコーディングがなぜ重要かを理解し、どんな言語でも「文字列」の表面下に何があるかを知ることができた。

制御フロー

条件とループはあらゆるアルゴリズムの骨格だ:

  • if/elseswitch でプログラムはデータに基づいて異なるパスをとる。
  • whilefor ループは処理を繰り返す。これらはほぼあらゆる処理タスクのイテレーションの構成要素だ。

メモリ

メモリはコースの中で最大の概念的投資であり、Rustへの直接的な恩恵が最も大きい部分だ。

メモリレイアウトでは、実行中のプログラムのメモリがコード、データ、スタック、ヒープの4つの領域に分かれていることを学んだ。**スタック(stack)**はローカル変数を自動的に管理する: 関数呼び出しごとにフレームがプッシュされ、リターン時にポップされる。**ヒープ(heap)**は明示的に借りて使い、終わったら返さなければならない大きなプールだ。

ヒープメモリの確保ではそのモデルを実践した。Zig のアロケーター API でヒープメモリを要求し、メモリリーク(解放忘れ)とuse-after-freeバグ(解放済みメモリへのアクセス)について学び、それらがなぜ危険かを実際に確認した。

ポインターはスタックとヒープをつないだ。ポインターは単なる数値 — メモリアドレス — だが、データをコピーせずにプログラムの各部分間で共有するための根本的なツールだ。

データ構造

ハッシュマップは実際のプログラムで最もよく使われるデータ構造の一つを紹介した。ハッシュマップはキーと値のペアを保存し、エントリ数に関わらず平均O(1)定数時間で任意の値を取り出せる。

アルゴリズムと再帰

再帰(recursion)では、関数が同じ問題のより小さなバージョンを自分自身に呼び出すテクニックを学んだ。再帰構造は数学的定義を反映し、コールスタックを使って中間結果を追跡し、無限降下を防ぐベースケースが必要だ。またループを優先すべき場面についても見た。

なぜ Zig で、なぜここでコースが終わるのか

Zig は明示的な言語だ。アロケーションを隠さず、ガベージコレクターを持たず、マシンからあなたを守らない。その透明性があるからこそ、このプロジェクトの他のすべてが依存する概念を教えるのに理想的だった。

しかし Zig は目標ではない。Project Hematite は Rust の学習コースだ。Zig の章は、手動でメモリを管理することを学べる制御された環境として機能した — そうすることで Rust がそれを自動的に引き受けるとき、Rust が何をしてくれているかを正確に理解できる。コースはこれ以上 Zig を深掘りしない; コンピューターの動作について十分な知識を得た今、本物のプロダクション用途向けに設計された言語へと移る準備ができている。

これからへの接続

Rustへ

Rustの所有権システムは、Zigで実践した規律をコンパイル時に強制するものだ:

Zigで手動でやったことRustが自動でやること
終わったら allocator.free を呼ぶオーナーがスコープを外れる → メモリ解放
解放後にメモリにアクセスしない借用チェッカーがダングリング参照を拒否する
同じメモリを2回解放しない所有権は唯一; 二重解放はコンパイルエラー
コピーせずにデータを共有するためポインターを渡す参照 &T または &mut T を渡す

語彙は変わる — 所有権(ownership)借用(borrowing)ライフタイム(lifetimes) — しかし基礎となるモデルは Zig で構築したものと同一だ。違いは、あなたが強制する代わりにコンパイラーが強制することだ。

TypeScriptへ

つながりは一見わかりにくいが、確かに存在する。TypeScript は Zig より高いレベルで動作する — ガベージコレクター、動的ディスパッチ、ブラウザランタイムを持つ — しかし構築した基礎はそのまま活きる:

  • 型思考: TypeScriptの価値はその静的型システムにある。固定幅整数、精密な浮動小数点セマンティクス、強く型付けされた構造体を扱ってきたので、TypeScriptの型アノテーションは異質なものではなく直感的に感じるはずだ。
  • データ構造: JavaScriptのオブジェクトは内部的にはハッシュマップだ。キーハッシュ、平均O(1)ルックアップ、最悪ケースの動作についての理解はそのまま適用できる。
  • アルゴリズム的思考: Zigで実践した再帰は言語中立なスキルだ。TypeScriptでも同じように機能する。

まとめ

  • プリミティブ型: ブール値、固定幅整数(符号付き・符号なし)、IEEE 754 浮動小数点、バイトスライスとしての文字列。各型は既知のバイト数を占有し、固有の算術規則を持つ。
  • 制御フロー: if/elseswitchwhilefor ループはあらゆるアルゴリズムの構成要素だ。
  • メモリ領域: コード、データ、スタック、ヒープ。スタックは自動で高速だが、サイズとライフタイムが限られる。ヒープは大きく永続的だが、明示的な管理が必要だ。
  • ポインター: メモリアドレスを格納する値 — コピーせずにデータを共有し、コンパイル時にサイズが不明な構造体を構築するための根本的なツール。
  • ハッシュマップ: 平均O(1)時間ルックアップを持つキーと値のストア、実践で最もよく使われるデータ構造の一つ。
  • 再帰: 問題をそれ自身のより小さなバージョンに還元して解決し、ベースケースで停止する。制限のない再帰はスタックオーバーフローを引き起こす。
  • これらすべてが転用できる: Rustの所有権モデル、TypeScriptの型システム、そしてどんな言語でも必要なアルゴリズム的思考へ。

次のステップ

このプロジェクトがカバーする2つの主要トラックに進む準備ができた:

  • Introduction to Rust Language — RustはProject Hematiteの主要言語だ。Zigで構築したすべてが Rustの所有権、借用、ライフタイムにどう直接マッピングされるかを確認するために、ここから始めよう。
  • Introduction to JavaScript & TypeScript — TypeScriptは2025年時点で最も人気のあるプログラミング言語であり、現代のウェブの言語だ。RustとともにWebツールやフロントエンドアプリケーションを構築する場合は、ここから始めよう。

一方のトラックを終えてから他方を始める必要はない。多くの読者が両方を並行して学ぶ。