- ZigはRustに似た波かっこベースの構文を土台にしつつ、より単純な言語意味論と洗練された構文上の選択によって改善されている
- 整数リテラルはすべての型が
comptime_intとして始まり、代入時に明示的に変換され、文字列リテラルは\\ベースの簡潔な生文字列記法を使う
.x = 1形式のレコードリテラルはフィールド書き込みを検索しやすくし、すべての型は前置記法で一貫して表現される
and・orを制御フローのキーワードとして使い、if・loop構文では必要に応じて波かっこを省略でき、フォーマッタが安全性を保証する
- 名前空間なしですべてを式として扱うことで型・値・パターン構文を統合し、ジェネリクス・レコードリテラル・組み込み関数(
@import、@asなど)を簡潔に活用する
概要
- ZigはRustに似た見た目を持ちながら、より単純な言語構造を採用している
- 構文設計ではgrepしやすさ、構文の一貫性、不要な視覚ノイズの削減に注力している
整数リテラル
const an_integer = 92;
assert(@TypeOf(an_integer) == comptime_int);
const x: i32 = 92;
const y = @as(i32, 92);
- すべての整数リテラルは
comptime_int型
- 変数に代入する際は明示的に型を指定するか、
@asを使って変換する
var x = 92;の形は動作せず、明示的な型が必要
文字列リテラル
const raw =
\\Roses are red
\\ Violets are blue,
\\Sugar is sweet
\\ And so are you.
\\
;
- 各行が個別のトークンなのでインデントの問題がない
\\自体をエスケープする必要がない
レコードリテラル
const p: Point = .{
.x = 1,
.y = 2,
};
.x = 1形式は読み取りと書き込みの区別に有利
.{}記法はブロックと区別しつつ、結果の型へ自動変換される
型記法
u32 // 整数
[3]u32 // 長さ3の配列
?[3]u32 // null可能な配列
*const ?[3]u32 // 定数ポインタ
- すべての型は前置(prefix)記法
- 逆参照は後置記法(
ptr.*)
識別子
const @"a name with space" = 42;
- キーワード衝突を避けたり、特殊な名前を指定したりできる
関数宣言
pub fn main() void {}
fn add(x: i32, y: i32) i32 {
return x + y;
}
fnキーワードと関数名が隣接しており、検索しやすい
- 戻り値型の表記に
->を使わない
変数宣言
const mid = lo + @divFloor(hi - lo, 2);
var count: u32 = 0;
制御フロー: and/or
while (count > 0 and ascii.isWhitespace(buffer[count - 1])) {
count -= 1;
}
and、orは制御フローのキーワード
- ビット演算には
&、|を使う
if文
.direction = if (prng.boolean()) .ascending else .descending;
- 丸かっこは必須、波かっこは任意
zig fmtが安全なフォーマットを保証する
ループ
for (0..10) |i| {
print("{d}\n", .{i});
} else @panic("loop safety counter exceeded");
for、whileはいずれもelse節をサポート
- イテレータと要素名が直感的に配置されている
名前空間と名前解決
const std = @import("std");
const ArrayList = std.ArrayList;
- 変数のシャドーイングは禁止
- 名前空間やグロブインポートはない
すべては式
const E = enum { a, b };
const e: if (true) E else void = .a;
- 型・値・パターン構文を統合している
- 型の位置に条件式を置ける
ジェネリクス
fn ArrayListType(comptime T: type) type {
return struct {
fn init() void {}
};
}
var xs: ArrayListType(u32) = .init();
- ジェネリクスは関数呼び出し構文(
Type(T))で表現する
- 型引数は常に明示する
組み込み関数
const foo = @import("./foo.zig");
const num = @as(i32, 92);
@接頭辞でコンパイラ提供機能を呼び出す
@importはファイルパスを明確に示す
- 引数は必ず文字列リテラルでなければならない
結論
- Zigの構文は小さな選択の積み重ねによって読みやすい言語を作り上げた事例
- 機能数を減らせば必要な構文も減り、構文同士の衝突可能性も低下する
- 既存言語の優れたアイデアを取り入れつつ、必要なときには大胆に新しい構文を導入している
まだコメントはありません。