一键导入
zig
Guides Zig 0.17 development-line code, migrations, std.Io usage, and build-system updates. Use when writing, reviewing, or upgrading Zig code for Zig 0.17.x.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Guides Zig 0.17 development-line code, migrations, std.Io usage, and build-system updates. Use when writing, reviewing, or upgrading Zig code for Zig 0.17.x.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | zig |
| description | Guides Zig 0.17 development-line code, migrations, std.Io usage, and build-system updates. Use when writing, reviewing, or upgrading Zig code for Zig 0.17.x. |
| license | MIT |
| compatibility | Requires a Zig 0.17.x compiler; development snapshots may change before the stable release. |
| metadata | {"version":"0.17.0-dev","language":"zig","category":"programming-language"} |
Write and port code against the installed Zig 0.17 compiler rather than older online examples.
This skill targets the Zig 0.17.x development line. Zig 0.17 is not assumed to be stable, so APIs can change between development snapshots. Run scripts/check-zig-version.sh before relying on this guide.
Do not describe development APIs as final release behavior. When this guide and the installed compiler disagree, the installed compiler is authoritative.
zig env and note .version, .std_dir, and .lib_dir..std_dir for exact signatures and doc comments.zig std for generated standard-library documentation..lib_dir.Never hardcode a Nix store path or another machine's Zig installation path.
Zig 0.17 continues the explicit-I/O and allocator-unmanaged model introduced during the 0.16 cycle:
std.Io to operations that perform I/O, sleep, time, or secure randomness.pub fn main(init: std.process.Init) !void when the program needs I/O, allocation, arguments, or environment data.std.Io.Reader or std.Io.Writer interface.std.ArrayList do not store an allocator; pass the allocator to mutating and cleanup methods.std.lang for language/compiler declarations. std.builtin is deprecated and scheduled for removal after 0.17.Supported entrypoint shapes include:
const std = @import("std");
pub fn main() !void {}
pub fn main(init: std.process.Init.Minimal) !void {
_ = init;
}
pub fn main(init: std.process.Init) !void {
const arena = init.arena.allocator();
const args = try init.minimal.args.toSlice(arena);
_ = args;
var buffer: [4096]u8 = undefined;
var file_writer: std.Io.File.Writer =
.init(.stdout(), init.io, &buffer);
const writer = &file_writer.interface;
try writer.print("hello {s}\n", .{"Zig 0.17"});
try writer.flush();
}
Use std.debug.print only for diagnostics. Explicitly flush buffered output.
Environment and process arguments are supplied through std.process.Init; do not rely on removed process-global APIs.
Use std.Io.Reader and std.Io.Writer, not the removed lowercase std.io generic interfaces.
var input: std.Io.Reader = .fixed("abc");
const first = try input.takeByte();
_ = first;
var storage: [128]u8 = undefined;
var output: std.Io.Writer = .fixed(&storage);
try output.print("{d}", .{42});
const bytes = output.buffered();
_ = bytes;
Common migrations:
| Older API | Zig 0.17 API |
|---|---|
std.io | std.Io |
std.io.fixedBufferStream | std.Io.Reader.fixed / std.Io.Writer.fixed |
readByte | takeByte |
readInt | takeInt |
readBytesNoEof(N) | takeArray(N) |
std.time.sleep | std.Io.sleep |
std.crypto.random | randomness through std.Io |
std.net | std.Io.net |
Read a complete file with an explicit I/O implementation, allocator, and limit:
const data = try std.Io.Dir.cwd().readFileAlloc(
init.io,
"input.txt",
init.gpa,
.limited(1024 * 1024),
);
defer init.gpa.free(data);
Reaching the limit returns error.StreamTooLong; the limit is an exclusive ceiling.
std.ArrayList is allocator-unmanaged:
var list: std.ArrayList(u8) = .empty;
defer list.deinit(gpa);
try list.append(gpa, 'a');
try list.appendSlice(gpa, "bc");
const last: ?u8 = list.pop();
_ = last;
Key migrations:
std.ArrayList(T).init(gpa) becomes std.ArrayList(T) = .empty or try .initCapacity(gpa, n).gpa to append, appendSlice, growth methods, deinit, and toOwnedSlice.popOrNull() becomes pop(), which returns ?T; use pop().? only when non-empty is guaranteed.std.array_hash_map.Auto, .String, or .Custom over deprecated old names.std.mem.find* names, such as findScalar, findScalarLast, and findAny, instead of indexOf* names.containsAtLeastScalar(T, slice, element, minimum) places the element before the count.Call writer.print; do not call the removed std.fmt.format helper.
{f} for values implementing a format method.{any} for generic structural formatting.pub fn format(value: @This(), writer: *std.Io.Writer) std.Io.Writer.Error!void {
try writer.print("{d}", .{value.number});
}
Use {x} / {X} for byte-slice hex, {B} / {Bi} for byte sizes, and {D} for durations. Consult local std.Io.Writer formatting docs for snapshot-specific specifiers.
@Type is removed. Use the dedicated type-construction builtins:
| Removed | Replacement |
|---|---|
@Type(.int) | @Int(signedness, bits) |
@Type(.pointer) | @Pointer(size, attributes, child, sentinel) |
@Type(.@"struct") | @Struct(...) |
@Type(.@"enum") | @Enum(...) |
@Type(.@"union") | @Union(...) |
@Type(.@"fn") | @Fn(...) |
| tuple reification | @Tuple(types) |
| enum-literal type | @EnumLiteral() |
Inspect the installed language reference for exact builtin parameters. Do not copy std.builtin.Type-based examples from older Zig versions.
Vector/array value coercion does not imply pointer-layout compatibility. Do not reinterpret pointers between vectors and arrays with @ptrCast; use explicit value conversion or @bitCast where semantically valid.
@cImport is deprecated. Translate C in build.zig and import the resulting module:
const translated = b.addTranslateC(.{
.root_source_file = b.path("src/api.h"),
.target = target,
.optimize = optimize,
});
const root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.imports = &.{.{
.name = "c",
.module = translated.createModule(),
}},
});
Use const c = @import("c"); in Zig source. Verify std.Build.Step.TranslateC locally because the development API can move.
Create a root module explicitly and pass it to compile steps:
const exe = b.addExecutable(.{
.name = "app",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
}),
});
Apply module concerns to exe.root_module: C sources, assembly, objects, imports, include paths, linked libraries, frameworks, link_libc, and link_libcpp. Avoid deprecated Step.Compile forwarding methods.
build.zig.zon requires an enum-literal name and package fingerprint:
.{
.name = .app,
.fingerprint = 0x123456789abcdef0,
.version = "0.1.0",
.dependencies = .{},
}
Relevant CLI changes:
zig init --minimal / -m, not --strip / -s.zig build test --test-timeout 500ms; durations require a unit.zig build --webui[=ip] enables the build UI; check zig build --help because development flags can change.Step.Run file arguments as potentially working-directory-relative, not necessarily absolute.scripts/check-zig-version.sh.zig fmt before interpreting parser cascades as API failures.build.zig.zon and build.zig first.std.builtin usage.std.process.Init, then thread std.Io through I/O boundaries.std.mem.find* calls.zig build test.Avoid compatibility wrappers unless the project explicitly supports multiple Zig versions. Zig has no stable standard-library compatibility promise before 1.0; direct code for the pinned compiler is usually simpler.