世界を動かす技術を、日本語で。

Zigの破壊的変更 – 初期のWritergate

2025年7月4日原文(github.com)

概要

  • Zigの std.ioリーダー/ライターAPI が大幅に刷新
  • 非ジェネリック化バッファ位置の変更 による最適化
  • フォーマット印刷やAPI呼び出しに 破壊的変更
  • 旧APIは非推奨、新APIへの適応方法も案内
  • 今後も段階的に関連変更を 順次マージ予定

Zig 標準I/Oリーダー・ライターAPI大刷新の概要

  • 既存の std.ioリーダー/ライター全廃止、新しい std.io.Reader/Writer へ統一
  • 非ジェネリック型 採用、バッファを インターフェース側 に配置
  • 最適化の透明性 確保、バッファ操作はホットパスで直接処理
  • vtable呼び出し はバッファが一杯の時のみ発生
  • 破壊的変更 となるため、移行には注意が必要

主なAPI変更点と移行ガイド

  • フォーマット関連のAPIが 大幅変更、既存コードは -freference-trace で修正箇所特定推奨
  • 主なリネーム例
    • std.fs.File.reader → std.fs.File.deprecatedReader
    • std.fs.File.writer → std.fs.File.deprecatedWriter
    • std.fmt.format → std.fmt.deprecatedFormat
    • std.fmt.fmtSliceEscapeLower/Upper → std.ascii.hexEscape
    • std.fmt.fmtSliceHexLower/Upper → {x}/{X}
    • std.fmt.fmtIntSizeDec/Bin → {B}/{Bi}
    • std.fmt.fmtDuration/DurationSigned → {D}
  • フォーマットメソッドのシグネチャ変更
    • *anytype → std.io.Writer
    • FormatOptions削除
    • std.fmt.Formatterコンテキスト型を明示的に
  • 旧APIは非推奨 (削除はまだ)
    • GenericReader/Writer, AnyReader/Writer → Reader/Writer
  • adaptToNewApi() による旧APIから新APIへの アダプタ利用例 あり

新APIの特徴と利点

  • 便利な新API を多数追加、パフォーマンス向上、非ジェネリック化
  • デリミタまでの読み込み が簡単に
  • 他言語にはない独自概念
    • discard (読み込み時の無視):不要データの効率的スキップ
    • splat (書き込み時のmemset的操作):O(M*N)→O(M)の効率化
    • ファイル送信 :OSがサポートすればfd-to-fdコピー可能
  • バッファ管理 :ユーザー側でバッファ提供、必要サイズは実装が決定

std.fs.File.Reader/Writerの新機能

  • Reader :ファイルハンドルに関する情報の メモ化
    • statによるサイズやエラー
    • 現在のシーク位置
    • シーク時のエラー
    • 位置指定/ストリーミング読み込み の判定
    • fd-to-fdシステムコール 利用可否
  • Writer :書き込み時にも同様のメモ化

今回の変更に含まれない内容

  • I/O as an InterfaceAsync/Await復活 は含まず
  • 以下のリワークや削除も未着手
    • tls, http, json, zon, zstd, flate, zip, パッケージ取得
    • fifo.LinearFifo削除
    • 非推奨APIの完全削除
  • これらは 別ブランチで順次PR予定

今後のマージ計画とTODO

  • テスト失敗の修正
  • std libのテスト修正
  • std.io.WriterのTODO解決
  • std.fs.File.Writerの実装完了 (特に位置指定モード対応)
  • count: usizeとcount: u64の扱い検討
  • manifestのキャッシュ処理の互換性確認

まとめと今後の展望

  • 大規模なAPI刷新 により、ZigのI/Oはより 最適化・便利化
  • 既存コードの修正は必須、移行ガイドを参考に対応推奨
  • 今後も 段階的な変更 を予定、開発者は継続的なキャッチアップが重要

Hackerたちの意見

タイトルを見たとき、これが実装されるのかと思ったよ。 https://github.com/ziglang/zig/issues/5973

だから、自動化ツールがあって、言語や標準ライブラリのセマンティックな変更を行えるのはいいことだよね。Goにはgo fixがあって、1.0以前の頃にしか使われてなかったと思うけど、これは失われることはないんだ。この手のツールはリンターやリファクタリングツールの基盤として使えるからね。Zigにもそんな解決策はあるのかな?

zig fmtには、新しいZigバージョンにソースコードをアップグレードするための自動修正がいくつかあるけど、私の知る限り、言語の変更にしか対応してなくて、標準ライブラリの変更には対応してないんだよね。

これに関しては、Zigのロードマップ2026のストリームで他のことと一緒に発表されたんだ。VOD: https://youtu.be/x3hOiOcbgeA

趣味でZigを開発している身としては、こんな基本的な部分での破壊的変更を見るのは残念だけど、1.0前の言語で開発するってことはそういうことだって理解してるよ。Zigチームが過去よりも移行を手助けすることにもっと投資してくれることを願ってる。過去の破壊的変更の経験から言うと、下流の開発者はどう修正すればいいかの明確なガイダンスなしに放置されちゃったんだ。Zig 0.12.0(ちょうど1年前にリリースされた)では、ビルドシステムにたくさんの破壊的変更があったけど、リリースノートには全く説明がなかったんだ。私が言いたいことを理解するには、Zig 0.11.0プロジェクトで行った変更[0]を見て、それからリリースノート[1]でその変更についてのガイダンスを探してみて。ほとんどの破壊的変更は言及すらされてなくて、0.11.0から0.12.0への移行方法なんて全然説明されてないよ。 >「君たちの中には死ぬ者もいるだろうが、それは私が受け入れる犠牲だ。」 >-ロード・ファークアッド [0] https://github.com/mtlynch/zenith/pull/90/files#diff-f87bb35... [1] https://ziglang.org/download/0.12.0/release-notes.html

hareの例を興味深く見てるよ[0]。それに、シャrekが大好きなのは皮肉じゃないよ。昔、NYCの小さなアパートでShrek Retoldの視聴パーティーを開いたことがあるんだ :D [0] https://harelang.org/blog/2025-06-11-hare-update/ [1] https://www.youtube.com/watch?v=pM70TROZQsI

だから、bunみたいなプロダクションプロジェクトがZigを使うって聞くと驚いちゃうんだよね。言語自体が悪い選択だとは思わないけど(デザインの決定にはいくつか異議があるけど)、こんな風に破壊的な変更があると、大きなコードベースで頻繁に1.0未満の言語を使うのは面倒だなって思う。

言語やライブラリの作者が、LLMが最初の修正を試みるために必要な変更を詳しく説明した良いプロンプトを含めてくれたらいいなと思う。決定論的なコードモッドでできればもっといいけど、プロンプトの方が書きやすいよね。

実際のAPIについて、破壊的変更の側面ではなくて、ちょっと話を始めたいんだけど、Reader.stream(writer, limit)Reader.streamRemaining(writer)の関数は、プッシュベースのデータ変換パイプライン(GREPや圧縮/暗号化みたいな)を構築するのに特にエレガントだと思う。状態機械のためにWriterインターフェースを実装して、出力を別のWriterに流し込むだけで、バイトがどう来てどう出て行くか(ソケットでも共有メモリでもファイルでも)を気にしなくて済むんだ。バッファサイズを設定するだけで、ゼロに設定することもできるみたいだし!Writer.sendFile()もいいね。こういうプリミティブを「ジェネリックインターフェース」で提供しているストリーム抽象は他に知らないよ。普通はストリームを「FileStream」にダウンキャストして、ファイルディスクリプタを直接扱わなきゃいけないから。

インターフェースのsendfileについてだけど、これは重要なんだ。なぜなら、ストリームを「FileStream」にダウンキャストするのは、パイプラインがA -> Bのときはうまくいくけど、途中にアイテムを挿入すると(A -> B -> C)崩れちゃうから。今、File -> tar -> HTTP(Transfer-Encoding: chunked) -> Socketのデモを持ってるけど、直接fd-to-fdコピーがチェーン全体を通過するんだ!

こんな大きな変化があると、Zigが今後他のデザイン選択を見直して改善してくれるかもしれないって期待しちゃうね。

見直してほしい選択肢について詳しく教えてもらえる?

Hacker Newsで議論の続きを見る