概要
- Zigの構文は シンプル かつ 洗練 された設計
- RustやCなどの言語から 良い部分を継承 しつつ、独自の改良を加えている
- 整数リテラル や 生文字列 など、特有の直感的な記法
- 型宣言、関数宣言、制御構文 も分かりやすく統一
- 名前解決やスコープ管理 も明確で、可読性と保守性を重視
Zigの魅力的な構文
- Zigは 中括弧系言語 の中で、構文設計が非常に洗練されている言語
- Rust から多くを借用しつつ、よりシンプルな意味論によって改善
- 型推論ではなく、 暗黙のcomptime型変換 を採用
- 例:
const an_integer = 92;→ 型はcomptime_int
- 例:
- 整数リテラル にはサフィックスが不要
- 型変換は代入時や明示的な型指定で行う
var x = 92;のような記法は基本的に不可、明示的な型指定が必要
生文字列リテラル
- Zigの生文字列は
\\で始まり、各行が独立したトークン- エスケープの必要がなく、 インデント問題も回避
- Rustの
r##""##記法に比べて、 可読性・保守性が高い - 行コメントのみ の仕様により、字句解析もシンプル
レコードリテラル
- C風の構文を採用
- 例:
const p: Point = .{ .x = 1, .y = 2, }
- 例:
.x = 1の記法により、 フィールド書き込み箇所のgrepが容易- データフロー解析 の効率化
型宣言とポインタ
- すべての型は 接頭辞型記法 (prefix)
- 例:
u32,[3]u32,*[3]u32
- 例:
- ポインタのデリファレンスは 後置 で記述
- 例:
ptr.* = 92;
- 例:
- Cの スパイラルルール の混乱を解消
識別子
- 生識別子 は
@"名前にスペース"のように記述- キーワードとの衝突回避や、特殊なエクスポート名に便利
- Zigの組み込み構文(例:
@TypeOf)や文字列と統一感
関数宣言
fn foo記法で宣言- C/Java系より 検索性・可読性が高い
- 戻り値型は 矢印(->)なし で記述
- 例:
fn add(x: i32, y: i32) i32
- 例:
- ラムダがない ため、戻り値型は常に必須
ローカル変数
constとvarでバインディング- 例:
const mid = lo + @divFloor(hi - lo, 2);
- 例:
- Rustの
constとは異なり、Zigのconstは comptimeではない - 型注釈は
'name' (':' Type)?の記法- 視認性と機械解析性が向上
制御フローと論理演算子
and,orを キーワード として使用- 例:
while (count > 0 and ascii.isWhitespace(...))
- 例:
- 短絡評価 が制御フローであることを明示
- ビット演算は従来通り
&,|を使用
明示的なreturn
- return文は必須
- 例:
fn add(x: i32, y: i32) i32 { return x + y; }
- 例:
- ブロック式の値はvoid
- セミコロン問題の回避、構文の一貫性
if式と三項演算子
- 括弧は必須、波括弧は任意
- 例:
.direction = if (prng.boolean()) .ascending else .descending,
- 例:
- フォーマッタが バグを誘発する書式ミスを検出
ループ
- Python同様、ループにelse句を付与可能
- ループ自体が 式 として使える
- 例:
pub const Word = for (.{ u8, u16, ... }) |W| { ... } else unreachable;
- 例:
- 無限ループ は明示的な条件で書く
- 安全性のため、上限を設けてpanicを利用
イテレータ構文
for (slice) |element| { ... }のように、 コレクションが先、変数が後- 直感的で読みやすい
名前の明確性とスコープ
- 変数のシャドウイング禁止
- バグの温床を排除
- 名前解決の複雑性を徹底排除
- プレリュードやグロブインポートなし
- 標準ライブラリ利用時も明示的にインポート
- 継承、ミックスイン、暗黙的なトレイト等なし
x.foo()は必ずx型に定義されたメソッド
- メソッドとフィールドの同名禁止
- 名前空間なし で、スコープ内の名前衝突を回避
foo.bar.baz記法で十分
Zigの構文設計は、 簡潔さ・明快さ・保守性 を最重視し、他言語の課題を巧みに解決している。 可読性・機械解析性・安全性 を追求する開発者にとって、Zigは非常に魅力的な選択肢。