リポジトリにある実行可能なサンプルを使った、実践的な言語解説。
Zero 入門 : Zero を学ぶ
作成 : クラスキャット・セールスインフォメーション
作成日時 : 05/28/2026
バージョン : v0.1.4
* 本記事は zerolang.ai の以下のページを参考にしています :
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。

Zero 入門 : Zero を学ぶ
リポジトリにある実行可能なサンプルを使った、実践的な言語解説。
プログラムは main で開始
最も簡単な例は examples/hello.0 です :
pub fun main(world: World) -> Void raises {
check world.out.write("hello from zero\n")
}
`pub` はエントリポイントをエクスポートします。`fun` は関数を宣言します。`main` は、隠しグローバル (変数) を使用する代わりに、World capability を受け取ります。
`-> Void` は、関数が有用な値を返さないことを意味します。`raises` は、関数が失敗する可能性があることを意味しています。
Run:
zero check examples/hello.0
出力例
ok
Capability を使用した副作用 (Effect)
Zero では出力は魔法ではありません。プログラムは `world.out` を通して以下のように出力します :
check world.out.write("hello from zero\n")
write は失敗する可能性があるため、`check` 付きで呼び出されます。`check` を使用する関数は `raises` を宣言する必要があります。
let で値をバインドする
examples/hello-let.0 はローカル・バインディングを導入しています :
pub fun main(world: World) -> Void raises {
let message = "hello from a binding\n"
check world.out.write(message)
}
値を変更すべきでない場合は、`let` を使用してください。値を意図的に再割り当てする場合にのみ、`let mut` を使用してください。
関数の記述
examples/add.0 はヘルパー関数を定義し、main からそれを呼び出します :
fun answer() -> i32 {
return 40 + 2
}
pub fun main(world: World) -> Void raises {
let value = answer()
if value == 42 {
check world.out.write("math works\n")
} else {
check world.out.write("math broke\n")
}
}
関数シグネチャには、パラメータ名と型を列挙します。戻り値の型は明示的に指定する必要があります。関数を値とともに終了したい場合は、`return` を使用します。
ネイティブコンパイラは現在、明示的な整数のビット幅を認識します :
i8 i16 i32 i64
u8 u16 u32 u64
usize isize
整数リテラルは、10進数、0x 16進数、0b 2進数、0o 8進数、_ 区切り文字、および _u8 や _usize などのサフィックスをサポートします。
リテラルはコンテキストに対してチェックされます。`let byte: u8 = 255` は正しく動作します。`let byte: u8 = 256` は `zero check` で失敗します。
既存の整数値は、その正確な型を保持します。プリミティブ整数型間で意図的に変換する場合は、`as` を使用してください :
let count: u32 = 0x12c_u32
let byte: u8 = count as u8
現在サポートされているキャストは、整数型から整数型への変換に限定されています。
f32 と f64 は、10進浮動小数点リテラルに使用できます。型指定のない浮動小数点リテラルのデフォルトは f64 です :
let ratio: f64 = 1.0e-3
let small: f32 = 0.5
let total = ratio + 2.0
浮動小数点数は、整数型とも、異なるビット幅同士でも、暗黙には混在しません。
char はまた、単一引用符で囲まれたバイトリテラル用の、バイトサイズの独立したプリミティブとして使用できます。整数との間でキャストはできません :
let letter: char = 'A'
let newline: char = '\n'
let same = letter == '\x41'
f16、Unicode スカラーリテラル、および非整数値に対するキャストは、現在の公開仕様 (surface) には含まれていません。
制御フローの使用
Zero には通常の if / else ブロックがあります :
if value == 42 {
check world.out.write("math works\n")
} else {
check world.out.write("math broke\n")
}
また、現在のネイティブサブセットでは while ループもサポートしています :
while keepGoing {
check world.out.write("loop\n")
}
整数カウンターが必要な場合は、レンジ `for` を使用してください :
for index in 0..4 {
if index == 2 {
continue
}
check world.out.write("tick\n")
}
最も近い (一番内側の) ループを抜け出すには `break` を使用し、次のイテレーションにスキップするには `continue` を使用します。
条件は Bool 型でなければならないため、truthy な整数に頼らず、値を明示的に比較してください。
直接的な条件式と明示的な状態を優先してください。チェッカーは不変バインディングへの代入を拒否するため、ループやアルゴリズムで実際に状態を変更する場合にのみ `let mut` を導入してください。
shape を使用したデータのモデル化
名前付きレコードには shape を使用します。examples/point.0 では point を定義し、それをヘルパー関数に渡しています :
shape Point {
x: i32,
y: i32,
}
fun sum(point: Point) -> i32 {
return point.x + point.y
}
pub fun main(world: World) -> Void raises {
let point = Point { x: 40, y: 2 }
let total = sum(point)
if total == 42 {
check world.out.write("point works\n")
}
}
shape リテラルは、そのフィールドに名前を付けます。フィールドへのアクセスには、value.field を使用します。
フィールドのデフォルト値の使用
shape では、呼び出し側が省略できるフィールドにデフォルト値を設定できます :
shape Counter {
value: i32 = 0,
}
let counter = Counter {}
デフォルト値は、通常の具体的なイニシャライザーへ展開されます。フィールドにデフォルト値が設定されていない場合、shape リテラルは明示的に初期化する必要があります。
enum と choice で選択肢を表現する
名前の固定されたセットに対しては enum を使用します :
enum Status {
ready,
failed,
}
ペイロードを持つ可能性がある選択肢の場合は、choice を使います :
choice Result {
ok: i32,
err: String,
}
examples/result-choice.0 はペイロードの選択肢を構築し、それに一致させます :
let result: Result = Result.ok(42)
match result {
.ok => value {
if value == 42 {
check world.out.write("choice ok\n")
}
}
.err => message {
check world.out.write("choice err\n")
}
}
match はすべてのケースを扱う (exhaustive) 必要があります。選択肢 (choice) に ok と err がある場合は、その両方に対応します。選択肢 (choice case) のペイロードをその分岐 (arm) 内で束縛するには `=> name` を使います。
標準ライブラリ・モジュールのインポート
`use` を使用して標準ライブラリモジュールをインポートします。examples/codec-varint.0 は std.codec を使用します :
use std.codec
pub fun main(world: World) -> Void raises {
let len = std.codec.encodedVarintLen(300)
let checksum = std.codec.crc32("zero")
if len == 2 && checksum > 0 {
check world.out.write("codec primitives ok\n")
}
}
examples/parse-cursor.0 は std.parse を使用しています :
use std.parse
pub fun main(world: World) -> Void raises {
let digit = std.parse.isAsciiDigit("7")
let ident = std.parse.isIdentifierStart("_")
if digit && ident {
check world.out.write("parse primitives ok\n")
}
}
現在のネイティブコンパイラは、std.mem、std.codec、std.parse、そして経過時間を中心にした (duration-focused) std.time の初期段階のヘルパーをサポートしています。
コーデックヘルパーは、`std.codec.readU16(…) -> u16` のように、ドキュメントに記載されている (ビット) 幅を返すようになりました。
CLI 向けのヘルパーも利用可能です :
pub fun main(world: World) -> Void raises {
let first = std.args.get(1)
if first.has {
let written = std.fs.write(".zero/out/name.txt", first.value)
if written > 0 {
check world.out.write("wrote argument\n")
}
}
}
std.args.get は、要求された引数が存在しない可能性があるため、Maybe<String> を返します。
現在の std.fs ヘルパーは hosted (ホスト環境依存) API です。Fs、File、owned<File> の具体的なリソース例が必要な場合は、標準ライブラリのリファレンスを参照してください。
パッケージの構成
パッケージは、zero.json マニフェストと、src/ ディレクトリ下のソースファイルで構成されます :
{
"package": { "name": "systems-package", "version": "0.1.0" },
"targets": { "cli": { "kind": "exe", "main": "src/main.0" } }
}
examples/systems-package/src/main.0 はモジュールとローカル宣言をインポートします :
use std.codec
use std.parse
use std.time
pub fun main(world: World) -> Void raises {
defer cleanup()
let current: Status = status()
let result: Result = Result.ok
let word = std.codec.readU32("abcd")
let digits = std.parse.scanDigits("123abc")
let duration = std.time.add(std.time.ms(5), std.time.seconds(1))
if digits == 3 && word > 0 && std.time.asMsFloor(duration) > 0 {
check world.out.write("systems package\n")
}
}
Check the package:
zero check examples/systems-package
テストの実行
Zero のテストブロックはソースコードのすぐ隣に置かれます :
test "addition is stable" {
expect(40 + 2 == 42)
}
Run tests with:
zero test conformance/native/pass/test-blocks.0
zero test --json --filter addition conformance/native/pass/test-blocks.0
失敗したテストには、失敗したテスト名と非ゼロの終了コードが含まれます。
クロスターゲットのチェック
ターゲット名は明示的です。サポート状況を確認するには `zero targets` を使用し、それから、check, build, graph, や size に –target オプションを渡します :
zero targets
zero check --target linux-musl-x64 examples/memory-package
zero build --target linux-musl-x64 examples/memory-package --out .zero/out/memory-package
チェッカーは、ターゲットに依存しない (target-neutral) ビルドにおけるホスト型 std.fs のような、利用できない機能を拒否します。
診断機能 (Diagnostics) の使用
診断機能は人間とエージェントの両方に対して十分に安定しています :
zero check --json conformance/check/fail/unknown-name.0
zero explain NAM003
zero fix --plan --json conformance/check/fail/unknown-name.0
各 JSON 診断には、コード、範囲 (span)、期待値/実際値フィールド、ヘルプ、安全性修正、メタデータ修復が含まれます。
defer を使用したクリーンアップの理解
`defer cleanup()` は、現在のスコープの終了時にクリーンアップをスケジュールします :
pub fun main(world: World) -> Void raises {
defer cleanup()
check world.out.write("work\n")
}
スコープが終了する際に実行される必要があるクリーンアップ処理には defer を使用します。これは、return、break、continue による終了も含まれます。
以上