zig-0.15

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zig 0.15.x Programming Guide

Zig 0.15.x 编程指南

Version Scope: This skill is pinned to Zig 0.15.x (specifically 0.15.2). For master/nightly builds, APIs may differ. Always check official docs for your version.
This skill ensures correct Zig 0.15.x API usage. Many LLMs have outdated Zig knowledge (0.11-0.14), causing compilation errors.
Official Documentation (0.15.2):
Community Resources (0.15.x):
Production Zig Codebases (learn from real-world projects):
Learning Resources (All 0.15.x Compatible):
Mitchell Hashimoto's Zig Libraries (Ghostty author, high quality):
Compiler/Toolchain:
AI/ML:
Blockchain/Ethereum:
Ecosystem Index:
For Other Versions:
版本范围:本技能适配Zig 0.15.x版本(具体为0.15.2)。 对于master/nightly构建版本,API可能存在差异,请务必查阅对应版本的官方文档。
本技能确保你正确使用Zig 0.15.x的API。许多大语言模型对Zig的认知还停留在0.11-0.14版本,这会导致编译错误。
官方文档(0.15.2版本)
社区资源(0.15.x版本)
生产级Zig代码库(从实际项目中学习):
学习资源(全部适配0.15.x版本)
Mitchell Hashimoto的Zig库(Ghostty作者,高质量):
编译器/工具链
AI/ML领域
区块链/以太坊领域
生态系统索引
其他版本资源

Critical API Changes in Zig 0.15

Zig 0.15中的关键API变更

ArrayList (BREAKING)

ArrayList(破坏性变更)

All mutating methods now require explicit
allocator
parameter:
zig
// ❌ WRONG (0.13 and earlier)
var list = std.ArrayList(T).init(allocator);
try list.append(item);
try list.appendSlice(items);
_ = try list.addOne();
_ = try list.toOwnedSlice();

// ✅ CORRECT (0.15+)
var list = try std.ArrayList(T).initCapacity(allocator, 16);
defer list.deinit(allocator);
try list.append(allocator, item);
try list.appendSlice(allocator, items);
_ = try list.addOne(allocator);
_ = try list.toOwnedSlice(allocator);

// AssumeCapacity variants do NOT need allocator
list.appendAssumeCapacity(item);
Method0.130.15+
append
try list.append(item)
try list.append(allocator, item)
appendSlice
try list.appendSlice(items)
try list.appendSlice(allocator, items)
addOne
try list.addOne()
try list.addOne(allocator)
ensureTotalCapacity
try list.ensureTotalCapacity(n)
try list.ensureTotalCapacity(allocator, n)
toOwnedSlice
try list.toOwnedSlice()
try list.toOwnedSlice(allocator)
deinit
list.deinit()
list.deinit(allocator)
所有可变方法现在都需要显式传入
allocator
参数:
zig
// ❌ 错误写法(0.13及更早版本)
var list = std.ArrayList(T).init(allocator);
try list.append(item);
try list.appendSlice(items);
_ = try list.addOne();
_ = try list.toOwnedSlice();

// ✅ 正确写法(0.15+版本)
var list = try std.ArrayList(T).initCapacity(allocator, 16);
defer list.deinit(allocator);
try list.append(allocator, item);
try list.appendSlice(allocator, items);
_ = try list.addOne(allocator);
_ = try list.toOwnedSlice(allocator);

// AssumeCapacity系列方法不需要传入allocator
list.appendAssumeCapacity(item);
方法0.13版本写法0.15+版本写法
append
try list.append(item)
try list.append(allocator, item)
appendSlice
try list.appendSlice(items)
try list.appendSlice(allocator, items)
addOne
try list.addOne()
try list.addOne(allocator)
ensureTotalCapacity
try list.ensureTotalCapacity(n)
try list.ensureTotalCapacity(allocator, n)
toOwnedSlice
try list.toOwnedSlice()
try list.toOwnedSlice(allocator)
deinit
list.deinit()
list.deinit(allocator)

HashMap

HashMap

Managed (stores allocator internally):
zig
var map = std.StringHashMap(V).init(allocator);
defer map.deinit();
try map.put(key, value);  // No allocator needed
Unmanaged (requires allocator for each operation):
zig
var map = std.StringHashMapUnmanaged(V){};
defer map.deinit(allocator);
try map.put(allocator, key, value);  // Allocator required
Managed版本(内部存储allocator):
zig
var map = std.StringHashMap(V).init(allocator);
defer map.deinit();
try map.put(key, value);  // 不需要传入allocator
Unmanaged版本(每次操作都需要传入allocator):
zig
var map = std.StringHashMapUnmanaged(V){};
defer map.deinit(allocator);
try map.put(allocator, key, value);  // 必须传入allocator

Writergate: New std.Io.Writer and std.Io.Reader (MAJOR REWRITE)

Writergate:全新的std.Io.Writer和std.Io.Reader(重大重写)

Zig 0.15 introduces completely new I/O interfaces. All old
std.io
readers/writers are deprecated.
Zig 0.15引入了完全全新的I/O接口。所有旧的
std.io
读写器均已被弃用。

Key Changes

主要变更

  1. Non-generic: New interfaces are concrete types, not
    anytype
  2. Buffer in interface: User provides buffer, implementation decides minimum size
  3. Ring buffer based: More efficient peek and streaming operations
  4. Precise error sets: No more
    anyerror
    propagation
  1. 非泛型:新接口为具体类型,而非
    anytype
  2. 接口内置缓冲区:由用户提供缓冲区,实现层决定最小尺寸
  3. 基于环形缓冲区:更高效的peek和流式操作
  4. 精确的错误集合:不再传播
    anyerror

New stdout Pattern

新的stdout使用方式

zig
// ❌ WRONG (0.14 and earlier)
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello\n", .{});

// ✅ CORRECT (0.15+)
var stdout_buffer: [1024]u8 = undefined;
var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
const stdout: *std.Io.Writer = &stdout_writer.interface;

try stdout.print("Hello\n", .{});
try stdout.flush();  // Don't forget to flush!
zig
// ❌ 错误写法(0.14及更早版本)
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello\n", .{});

// ✅ 正确写法(0.15+版本)
var stdout_buffer: [1024]u8 = undefined;
var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
const stdout: *std.Io.Writer = &stdout_writer.interface;

try stdout.print("Hello\n", .{});
try stdout.flush();  // 不要忘记刷新!

Adapter for Migration

迁移适配工具

If you have old-style writers and need new interface:
zig
fn useOldWriter(old_writer: anytype) !void {
    var adapter = old_writer.adaptToNewApi(&.{});
    const w: *std.Io.Writer = &adapter.new_interface;
    try w.print("{s}", .{"example"});
}
如果你有旧风格的写入器,需要适配新接口:
zig
fn useOldWriter(old_writer: anytype) !void {
    var adapter = old_writer.adaptToNewApi(&.{});
    const w: *std.Io.Writer = &adapter.new_interface;
    try w.print("{s}", .{"example"});
}

New Reader API

新的Reader API

zig
// Reading lines with delimiter
while (reader.takeDelimiterExclusive('\n')) |line| {
    // process line
} else |err| switch (err) {
    error.EndOfStream => {},
    error.StreamTooLong => return err,
    error.ReadFailed => return err,
}
zig
// 按分隔符读取行
while (reader.takeDelimiterExclusive('\n')) |line| {
    // 处理行内容
} else |err| switch (err) {
    error.EndOfStream => {},
    error.StreamTooLong => return err,
    error.ReadFailed => return err,
}

HTTP Client (MAJOR REWRITE)

HTTP客户端(重大重写)

Zig 0.15.2 has both
fetch()
(high-level) and
request()
(low-level) APIs:
zig
// ✅ CORRECT: High-level fetch() API (Zig 0.15.2)
var client: std.http.Client = .{ .allocator = allocator };
defer client.deinit();

const result = try client.fetch(.{
    .location = .{ .url = "https://example.com/api" },
    .method = .GET,
});
// result.status contains the HTTP status

// ✅ CORRECT: Low-level request/response API (Zig 0.15.2)
var client: std.http.Client = .{ .allocator = allocator };
defer client.deinit();

const uri = try std.Uri.parse("https://example.com/api");

// Create request with client.request() (NOT client.open!)
var req = try client.request(.POST, uri, .{
    .extra_headers = &.{
        .{ .name = "Content-Type", .value = "application/json" },
    },
});
defer req.deinit();

// Send body (use @constCast for const slices)
try req.sendBodyComplete(@constCast("{\"key\": \"value\"}"));

// Receive response
var redirect_buf: [4096]u8 = undefined;
var response = try req.receiveHead(&redirect_buf);

// Check status
const status = @intFromEnum(response.head.status);
if (status >= 200 and status < 300) {
    // Read response body using std.Io.Reader
    var body_reader = response.reader(&redirect_buf);
    const body = try body_reader.allocRemaining(allocator, std.Io.Limit.limited(1024 * 1024));
    defer allocator.free(body);
}
Key API functions (verified in Zig 0.15.2):
  • client.request(method, uri, options)
    Request
  • client.fetch(options)
    FetchResult
  • req.sendBodyComplete(body)
    - sends body and flushes
  • req.sendBodiless()
    - for GET requests without body
  • req.receiveHead(buffer)
    Response
  • response.reader(buffer)
    *std.Io.Reader
  • reader.allocRemaining(allocator, limit)
    []u8
Zig 0.15.2同时提供
fetch()
(高层级)和
request()
(低层级)API:
zig
// ✅ 正确写法:高层级fetch() API(Zig 0.15.2)
var client: std.http.Client = .{ .allocator = allocator };
defer client.deinit();

const result = try client.fetch(.{
    .location = .{ .url = "https://example.com/api" },
    .method = .GET,
});
// result.status包含HTTP状态码

// ✅ 正确写法:低层级request/response API(Zig 0.15.2)
var client: std.http.Client = .{ .allocator = allocator };
defer client.deinit();

const uri = try std.Uri.parse("https://example.com/api");

// 使用client.request()创建请求(不要用client.open!)
var req = try client.request(.POST, uri, .{
    .extra_headers = &.{
        .{ .name = "Content-Type", .value = "application/json" },
    },
});
defer req.deinit();

// 发送请求体(对const切片使用@constCast)
try req.sendBodyComplete(@constCast("{\"key\": \"value\"}"));

// 接收响应
var redirect_buf: [4096]u8 = undefined;
var response = try req.receiveHead(&redirect_buf);

// 检查状态码
const status = @intFromEnum(response.head.status);
if (status >= 200 and status < 300) {
    // 使用std.Io.Reader读取响应体
    var body_reader = response.reader(&redirect_buf);
    const body = try body_reader.allocRemaining(allocator, std.Io.Limit.limited(1024 * 1024));
    defer allocator.free(body);
}
已验证的Zig 0.15.2关键API函数
  • client.request(method, uri, options)
    Request
  • client.fetch(options)
    FetchResult
  • req.sendBodyComplete(body)
    - 发送请求体并刷新
  • req.sendBodiless()
    - 用于无请求体的GET请求
  • req.receiveHead(buffer)
    Response
  • response.reader(buffer)
    *std.Io.Reader
  • reader.allocRemaining(allocator, limit)
    []u8

Base64 Encoding

Base64编码

zig
// ❌ WRONG (0.13)
const encoder = std.base64.standard;
const encoded = encoder.encode(&buf, data);

// ✅ CORRECT (0.15+)
const encoder = std.base64.standard.Encoder;
const encoded = encoder.encode(&buf, data);
zig
// ❌ 错误写法(0.13版本)
const encoder = std.base64.standard;
const encoded = encoder.encode(&buf, data);

// ✅ 正确写法(0.15+版本)
const encoder = std.base64.standard.Encoder;
const encoded = encoder.encode(&buf, data);

Ed25519 Cryptography (MAJOR CHANGES)

Ed25519加密(重大变更)

Key types are now structs, not raw byte arrays:
zig
const Ed25519 = std.crypto.sign.Ed25519;

// ❌ WRONG (0.13 - SecretKey was [32]u8)
const secret: [32]u8 = ...;
const kp = Ed25519.KeyPair.fromSecretKey(secret);

// ✅ CORRECT (0.15+ - SecretKey is struct with 64 bytes)
// From 32-byte seed (deterministic):
const seed: [32]u8 = ...;
const kp = try Ed25519.KeyPair.generateDeterministic(seed);

// From 64-byte secret key:
var secret_bytes: [64]u8 = ...;
const secret_key = try Ed25519.SecretKey.fromBytes(secret_bytes);
const kp = try Ed25519.KeyPair.fromSecretKey(secret_key);

// Get public key bytes:
const pubkey_bytes: [32]u8 = kp.public_key.toBytes();

// Get seed:
const seed: [32]u8 = kp.secret_key.seed();
Signature changes:
zig
// ❌ WRONG (0.13 - fromBytes returned error union)
const sig = try Ed25519.Signature.fromBytes(bytes);

// ✅ CORRECT (0.15+ - fromBytes does NOT return error)
const sig = Ed25519.Signature.fromBytes(bytes);
密钥类型现在为结构体,而非原始字节数组:
zig
const Ed25519 = std.crypto.sign.Ed25519;

// ❌ 错误写法(0.13版本 - SecretKey为[32]u8)
const secret: [32]u8 = ...;
const kp = Ed25519.KeyPair.fromSecretKey(secret);

// ✅ 正确写法(0.15+版本 - SecretKey为包含64字节的结构体)
// 从32字节种子生成(确定性):
const seed: [32]u8 = ...;
const kp = try Ed25519.KeyPair.generateDeterministic(seed);

// 从64字节密钥生成:
var secret_bytes: [64]u8 = ...;
const secret_key = try Ed25519.SecretKey.fromBytes(secret_bytes);
const kp = try Ed25519.KeyPair.fromSecretKey(secret_key);

// 获取公钥字节:
const pubkey_bytes: [32]u8 = kp.public_key.toBytes();

// 获取种子:
const seed: [32]u8 = kp.secret_key.seed();
签名相关变更:
zig
// ❌ 错误写法(0.13版本 - fromBytes返回错误联合类型)
const sig = try Ed25519.Signature.fromBytes(bytes);

// ✅ 正确写法(0.15+版本 - fromBytes不返回错误)
const sig = Ed25519.Signature.fromBytes(bytes);

Type Introspection Enums (Case Change)

类型自省枚举(大小写变更)

zig
// ❌ WRONG (0.13 - PascalCase)
if (@typeInfo(T) == .Slice) { ... }
if (@typeInfo(T) == .Pointer) { ... }
if (@typeInfo(T) == .Struct) { ... }

// ✅ CORRECT (0.15+ - lowercase/escaped)
if (@typeInfo(T) == .slice) { ... }
if (@typeInfo(T) == .pointer) { ... }
if (@typeInfo(T) == .@"struct") { ... }
if (@typeInfo(T) == .@"enum") { ... }
if (@typeInfo(T) == .@"union") { ... }
if (@typeInfo(T) == .array) { ... }
if (@typeInfo(T) == .optional) { ... }
zig
// ❌ 错误写法(0.13版本 - 大驼峰命名)
if (@typeInfo(T) == .Slice) { ... }
if (@typeInfo(T) == .Pointer) { ... }
if (@typeInfo(T) == .Struct) { ... }

// ✅ 正确写法(0.15+版本 - 小写/转义)
if (@typeInfo(T) == .slice) { ... }
if (@typeInfo(T) == .pointer) { ... }
if (@typeInfo(T) == .@"struct") { ... }
if (@typeInfo(T) == .@"enum") { ... }
if (@typeInfo(T) == .@"union") { ... }
if (@typeInfo(T) == .array) { ... }
if (@typeInfo(T) == .optional) { ... }

Custom Format Functions

自定义格式化函数

zig
// ❌ WRONG (0.13 - used {} format specifier)
pub fn format(
    self: Self,
    comptime fmt: []const u8,
    options: std.fmt.FormatOptions,
    writer: anytype,
) !void {
    _ = fmt;
    _ = options;
    try writer.writeAll("...");
}
// Usage: std.fmt.bufPrint(&buf, "{}", .{value});

// ✅ CORRECT (0.15+ - use {f} format specifier)
pub fn format(self: Self, writer: anytype) !void {
    _ = self;
    try writer.writeAll("...");
}
// Usage: std.fmt.bufPrint(&buf, "{f}", .{value});
zig
// ❌ 错误写法(0.13版本 - 使用{}格式说明符)
pub fn format(
    self: Self,
    comptime fmt: []const u8,
    options: std.fmt.FormatOptions,
    writer: anytype,
) !void {
    _ = fmt;
    _ = options;
    try writer.writeAll("...");
}
// 使用方式:std.fmt.bufPrint(&buf, "{}", .{value});

// ✅ 正确写法(0.15+版本 - 使用{f}格式说明符)
pub fn format(self: Self, writer: anytype) !void {
    _ = self;
    try writer.writeAll("...");
}
// 使用方式:std.fmt.bufPrint(&buf, "{f}", .{value});

JSON Parsing and Serialization

JSON解析与序列化

zig
const MyStruct = struct {
    name: []const u8,
    value: u32,
};

// ✅ CORRECT: Parsing (0.15+)
const json_str =
    \\{"name": "test", "value": 42}
;
const parsed = try std.json.parseFromSlice(MyStruct, allocator, json_str, .{});
defer parsed.deinit();
const data = parsed.value;

// ✅ CORRECT: Serialization (0.15.2 - writer-based API)
// Note: There is NO stringifyAlloc in 0.15.2!

// Method 1: Using std.json.Stringify with Allocating writer
var out: std.Io.Writer.Allocating = .init(allocator);
defer out.deinit();
var stringify: std.json.Stringify = .{
    .writer = &out.writer,
    .options = .{},
};
try stringify.write(data);
const json_output = out.written();

// Method 2: Using std.fmt with json.fmt wrapper
const formatted = try std.fmt.allocPrint(allocator, "{f}", .{std.json.fmt(data, .{})});
defer allocator.free(formatted);

// Method 3: To fixed buffer
var buf: [1024]u8 = undefined;
var fbs = std.io.fixedBufferStream(&buf);
var writer = fbs.writer();
var stringify2: std.json.Stringify = .{
    .writer = &writer.adaptToNewApi(&.{}).new_interface,
    .options = .{},
};
try stringify2.write(data);
const output = fbs.getWritten();
zig
const MyStruct = struct {
    name: []const u8,
    value: u32,
};

// ✅ 正确写法:解析(0.15+版本)
const json_str =
    \\{"name": "test", "value": 42}
;
const parsed = try std.json.parseFromSlice(MyStruct, allocator, json_str, .{});
defer parsed.deinit();
const data = parsed.value;

// ✅ 正确写法:序列化(0.15.2 - 基于写入器的API)
// 注意:0.15.2版本中没有stringifyAlloc!

// 方法1:使用std.json.Stringify和Allocating写入器
var out: std.Io.Writer.Allocating = .init(allocator);
defer out.deinit();
var stringify: std.json.Stringify = .{
    .writer = &out.writer,
    .options = .{},
};
try stringify.write(data);
const json_output = out.written();

// 方法2:使用std.fmt配合json.fmt包装器
const formatted = try std.fmt.allocPrint(allocator, "{f}", .{std.json.fmt(data, .{})});
defer allocator.free(formatted);

// 方法3:写入固定缓冲区
var buf: [1024]u8 = undefined;
var fbs = std.io.fixedBufferStream(&buf);
var writer = fbs.writer();
var stringify2: std.json.Stringify = .{
    .writer = &writer.adaptToNewApi(&.{}).new_interface,
    .options = .{},
};
try stringify2.write(data);
const output = fbs.getWritten();

Memory/Formatting

内存/格式化

zig
// Allocating format
const formatted = try std.fmt.allocPrint(allocator, "value: {d}", .{42});
defer allocator.free(formatted);

// Non-allocating format
var buffer: [256]u8 = undefined;
const result = try std.fmt.bufPrint(&buffer, "value: {d}", .{42});
zig
// 分配式格式化
const formatted = try std.fmt.allocPrint(allocator, "value: {d}", .{42});
defer allocator.free(formatted);

// 非分配式格式化
var buffer: [256]u8 = undefined;
const result = try std.fmt.bufPrint(&buffer, "value: {d}", .{42});

Common Error Messages and Fixes

常见错误信息及修复方案

ErrorCauseFix
expected 2 argument(s), found 1
ArrayList method missing allocatorAdd allocator as first argument
no field or member function named 'encode'
Using
std.base64.standard.encode
Use
std.base64.standard.Encoder.encode
no field or member function named 'open'
Using old HTTP APIUse
client.request()
or
client.fetch()
expected type 'SecretKey', found '[32]u8'
Ed25519 SecretKey is now structUse
generateDeterministic(seed)
expected error union type, found 'Signature'
Signature.fromBytes doesn't return errorRemove
try
enum has no member named 'Slice'
@typeInfo enum case changedUse lowercase
.slice
no field named 'root_source_file'
Old build.zig APIUse
root_module = b.createModule(...)
错误信息原因修复方案
expected 2 argument(s), found 1
ArrayList方法缺少allocator参数添加allocator作为第一个参数
no field or member function named 'encode'
使用了
std.base64.standard.encode
使用
std.base64.standard.Encoder.encode
no field or member function named 'open'
使用了旧的HTTP API使用
client.request()
client.fetch()
expected type 'SecretKey', found '[32]u8'
Ed25519的SecretKey现在是结构体使用
generateDeterministic(seed)
expected error union type, found 'Signature'
Signature.fromBytes不再返回错误移除
try
enum has no member named 'Slice'
@typeInfo枚举的成员名称已变更使用小写的
.slice
no field named 'root_source_file'
使用了旧的build.zig API使用
root_module = b.createModule(...)

Verification Workflow

验证流程

After writing Zig code:
  1. Run
    zig build
    to check for compilation errors
  2. If errors match patterns above, apply the 0.15 fix
  3. Run
    zig build test
    to verify functionality
  4. Use
    zig build -Doptimize=ReleaseFast test
    to catch UB
编写完Zig代码后:
  1. 运行
    zig build
    检查编译错误
  2. 如果错误匹配上述模式,应用0.15版本的修复方案
  3. 运行
    zig build test
    验证功能
  4. 使用
    zig build -Doptimize=ReleaseFast test
    捕获未定义行为(UB)

Build System (build.zig) Changes (MAJOR REWRITE)

构建系统(build.zig)变更(重大重写)

Executable Creation

可执行文件创建

zig
// ❌ WRONG (0.14 and earlier)
const exe = b.addExecutable(.{
    .name = "hello",
    .root_source_file = .{ .path = "src/main.zig" },
    .target = target,
    .optimize = optimize,
});

// ✅ CORRECT (0.15+)
const exe = b.addExecutable(.{
    .name = "hello",
    .root_module = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    }),
});
zig
// ❌ 错误写法(0.14及更早版本)
const exe = b.addExecutable(.{
    .name = "hello",
    .root_source_file = .{ .path = "src/main.zig" },
    .target = target,
    .optimize = optimize,
});

// ✅ 正确写法(0.15+版本)
const exe = b.addExecutable(.{
    .name = "hello",
    .root_module = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    }),
});

Library Creation

库创建

zig
// ❌ WRONG (0.14 - addSharedLibrary/addStaticLibrary)
const lib = b.addSharedLibrary(.{
    .name = "mylib",
    .root_source_file = .{ .path = "src/lib.zig" },
});

// ✅ CORRECT (0.15+ - unified addLibrary with linkage)
const lib = b.addLibrary(.{
    .name = "mylib",
    .linkage = .dynamic,  // or .static
    .root_module = b.createModule(.{
        .root_source_file = b.path("src/lib.zig"),
        .target = target,
        .optimize = optimize,
    }),
});
zig
// ❌ 错误写法(0.14版本 - 使用addSharedLibrary/addStaticLibrary)
const lib = b.addSharedLibrary(.{
    .name = "mylib",
    .root_source_file = .{ .path = "src/lib.zig" },
});

// ✅ 正确写法(0.15+版本 - 使用统一的addLibrary并指定linkage)
const lib = b.addLibrary(.{
    .name = "mylib",
    .linkage = .dynamic,  // 或.static
    .root_module = b.createModule(.{
        .root_source_file = b.path("src/lib.zig"),
        .target = target,
        .optimize = optimize,
    }),
});

Path Handling

路径处理

zig
// ❌ WRONG (0.14 - .path field)
.root_source_file = .{ .path = "src/main.zig" },

// ✅ CORRECT (0.15+ - use b.path())
.root_source_file = b.path("src/main.zig"),
zig
// ❌ 错误写法(0.14版本 - 使用.path字段)
.root_source_file = .{ .path = "src/main.zig" },

// ✅ 正确写法(0.15+版本 - 使用b.path())
.root_source_file = b.path("src/main.zig"),

Module Dependencies

模块依赖

zig
// ❌ WRONG (0.14)
exe.addModule("sdk", sdk_module);

// ✅ CORRECT (0.15+)
exe.root_module.addImport("sdk", sdk_module);
zig
// ❌ 错误写法(0.14版本)
exe.addModule("sdk", sdk_module);

// ✅ 正确写法(0.15+版本)
exe.root_module.addImport("sdk", sdk_module);

Target Options

目标选项

zig
// ❌ WRONG (0.14)
const target = b.standardTargetOptions(.{});
// then use target directly

// ✅ CORRECT (0.15+)
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const exe = b.addExecutable(.{
    .name = "app",
    .root_module = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,      // pass to createModule
        .optimize = optimize,  // pass to createModule
    }),
});
zig
// ❌ 错误写法(0.14版本)
const target = b.standardTargetOptions(.{});
// 直接使用target

// ✅ 正确写法(0.15+版本)
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const exe = b.addExecutable(.{
    .name = "app",
    .root_module = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,      // 传递给createModule
        .optimize = optimize,  // 传递给createModule
    }),
});

Testing

测试

zig
// ✅ CORRECT (0.15+)
const unit_tests = b.addTest(.{
    .root_module = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = b.graph.host,  // use b.graph.host for native target
    }),
});

const run_unit_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);
zig
// ✅ 正确写法(0.15+版本)
const unit_tests = b.addTest(.{
    .root_module = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = b.graph.host,  // 使用b.graph.host作为原生目标
    }),
});

const run_unit_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);

Complete build.zig Example

完整的build.zig示例

zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "hello",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });

    b.installArtifact(exe);

    const run_exe = b.addRunArtifact(exe);
    const run_step = b.step("run", "Run the application");
    run_step.dependOn(&run_exe.step);
}
zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "hello",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });

    b.installArtifact(exe);

    const run_exe = b.addRunArtifact(exe);
    const run_step = b.step("run", "Run the application");
    run_step.dependOn(&run_exe.step);
}

std.mem Patterns

std.mem使用模式

Memory Operations

内存操作

zig
// Copy memory
@memcpy(dest, src);  // Same as std.mem.copyForwards

// Set memory
@memset(buffer, 0);  // Zero-fill

// Compare memory
const equal = std.mem.eql(u8, slice1, slice2);

// Find in slice
const index = std.mem.indexOf(u8, haystack, needle);
zig
// 复制内存
@memcpy(dest, src);  // 与std.mem.copyForwards功能相同

// 设置内存
@memset(buffer, 0);  // 零填充

// 比较内存
const equal = std.mem.eql(u8, slice1, slice2);

// 在切片中查找
const index = std.mem.indexOf(u8, haystack, needle);

Alignment

对齐

zig
// Check alignment
const is_aligned = std.mem.isAligned(@intFromPtr(ptr), @alignOf(T));

// Align pointer
const aligned = std.mem.alignPointer(ptr, @alignOf(T));
zig
// 检查对齐
const is_aligned = std.mem.isAligned(@intFromPtr(ptr), @alignOf(T));

// 对齐指针
const aligned = std.mem.alignPointer(ptr, @alignOf(T));

std.io Patterns

std.io使用模式

Fixed Buffer Stream

固定缓冲区流

zig
var buf: [1024]u8 = undefined;
var fbs = std.io.fixedBufferStream(&buf);
const writer = fbs.writer();

try writer.writeAll("Hello");
try writer.print(" {d}", .{42});

const written = fbs.getWritten();  // "Hello 42"
zig
var buf: [1024]u8 = undefined;
var fbs = std.io.fixedBufferStream(&buf);
const writer = fbs.writer();

try writer.writeAll("Hello");
try writer.print(" {d}", .{42});

const written = fbs.getWritten();  // "Hello 42"

Counting Writer

计数写入器

zig
var counting = std.io.countingWriter(underlying_writer);
try counting.writer().writeAll("test");
const bytes_written = counting.bytes_written;  // 4
zig
var counting = std.io.countingWriter(underlying_writer);
try counting.writer().writeAll("test");
const bytes_written = counting.bytes_written;  // 4

Testing Patterns

测试模式

Testing Allocator (Detects Leaks)

测试分配器(检测内存泄漏)

zig
test "no memory leaks" {
    const allocator = std.testing.allocator;  // Auto-detects leaks
    
    const data = try allocator.alloc(u8, 100);
    defer allocator.free(data);  // MUST free or test fails
    
    // ... test code ...
}
zig
test "no memory leaks" {
    const allocator = std.testing.allocator;  // 自动检测泄漏
    
    const data = try allocator.alloc(u8, 100);
    defer allocator.free(data);  // 必须释放,否则测试失败
    
    // ... 测试代码 ...
}

Assertions

断言

zig
test "assertions" {
    try std.testing.expect(condition);              // Boolean
    try std.testing.expectEqual(expected, actual);  // Equality
    try std.testing.expectEqualSlices(u8, expected, actual);  // Slices
    try std.testing.expectError(error.SomeError, result);     // Error
    try std.testing.expectEqualStrings("hello", str);         // Strings
}
zig
test "assertions" {
    try std.testing.expect(condition);              // 布尔断言
    try std.testing.expectEqual(expected, actual);  // 相等断言
    try std.testing.expectEqualSlices(u8, expected, actual);  // 切片相等断言
    try std.testing.expectError(error.SomeError, result);     // 错误断言
    try std.testing.expectEqualStrings("hello", str);         // 字符串相等断言
}

Comptime Patterns

编译期模式

Type Reflection

类型反射

zig
fn serialize(comptime T: type, value: T) ![]u8 {
    const info = @typeInfo(T);
    
    switch (info) {
        .int => |i| {
            // Handle integer
            const byte_count = @divExact(i.bits, 8);
            // ...
        },
        .@"struct" => |s| {
            // Handle struct
            inline for (s.fields) |field| {
                // Process each field
                const field_value = @field(value, field.name);
                // ...
            }
        },
        else => @compileError("Unsupported type"),
    }
}
zig
fn serialize(comptime T: type, value: T) ![]u8 {
    const info = @typeInfo(T);
    
    switch (info) {
        .int => |i| {
            // 处理整数
            const byte_count = @divExact(i.bits, 8);
            // ...
        },
        .@"struct" => |s| {
            // 处理结构体
            inline for (s.fields) |field| {
                // 处理每个字段
                const field_value = @field(value, field.name);
                // ...
            }
        },
        else => @compileError("Unsupported type"),
    }
}

Optional Type Handling

可选类型处理

zig
fn getInner(comptime T: type) type {
    const info = @typeInfo(T);
    if (info == .optional) {
        return info.optional.child;
    }
    return T;
}
zig
fn getInner(comptime T: type) type {
    const info = @typeInfo(T);
    if (info == .optional) {
        return info.optional.child;
    }
    return T;
}

Pointer and Slice Patterns

指针与切片模式

Slice to Many-Item Pointer

切片转多元素指针

zig
const slice: []u8 = buffer[0..10];
const ptr: [*]u8 = slice.ptr;
zig
const slice: []u8 = buffer[0..10];
const ptr: [*]u8 = slice.ptr;

Creating Slices

创建切片

zig
// From array
const arr = [_]u8{ 1, 2, 3, 4, 5 };
const slice = arr[1..4];  // [2, 3, 4]

// From pointer + length
const slice = ptr[0..len];
zig
// 从数组创建
const arr = [_]u8{ 1, 2, 3, 4, 5 };
const slice = arr[1..4];  // [2, 3, 4]

// 从指针+长度创建
const slice = ptr[0..len];

Sentinel-Terminated Slices

哨兵终止切片

zig
// Null-terminated string
const str: [:0]const u8 = "hello";
const c_str: [*:0]const u8 = str.ptr;

// Get length without sentinel
const len = str.len;  // 5, not including null
zig
// 空终止字符串
const str: [:0]const u8 = "hello";
const c_str: [*:0]const u8 = str.ptr;

// 获取不含哨兵的长度
const len = str.len;  // 5,不包含空字符

Language Changes

语言变更

usingnamespace Removed

usingnamespace已被移除

The
usingnamespace
keyword has been completely removed in Zig 0.15.
zig
// ❌ WRONG (removed in 0.15)
pub usingnamespace @import("other.zig");

// ✅ CORRECT - explicit re-exports
pub const foo = @import("other.zig").foo;
pub const bar = @import("other.zig").bar;

// ✅ CORRECT - namespace via field
pub const other = @import("other.zig");
// Usage: other.foo, other.bar
Migration for mixins: Use zero-bit fields with
@fieldParentPtr
:
zig
// ❌ OLD mixin pattern
pub const Foo = struct {
    count: u32 = 0,
    pub usingnamespace CounterMixin(Foo);
};

// ✅ NEW mixin pattern (0.15+)
pub fn CounterMixin(comptime T: type) type {
    return struct {
        pub fn increment(m: *@This()) void {
            const x: *T = @alignCast(@fieldParentPtr("counter", m));
            x.count += 1;
        }
    };
}

pub const Foo = struct {
    count: u32 = 0,
    counter: CounterMixin(Foo) = .{},  // zero-bit field
};
// Usage: foo.counter.increment()
Zig 0.15中已完全移除
usingnamespace
关键字。
zig
// ❌ 错误写法(0.15版本已移除)
pub usingnamespace @import("other.zig");

// ✅ 正确写法 - 显式重导出
pub const foo = @import("other.zig").foo;
pub const bar = @import("other.zig").bar;

// ✅ 正确写法 - 通过字段命名空间
pub const other = @import("other.zig");
// 使用方式:other.foo, other.bar
Mixin迁移方案:使用零位字段配合
@fieldParentPtr
zig
// ❌ 旧的mixin模式
pub const Foo = struct {
    count: u32 = 0,
    pub usingnamespace CounterMixin(Foo);
};

// ✅ 新的mixin模式(0.15+版本)
pub fn CounterMixin(comptime T: type) type {
    return struct {
        pub fn increment(m: *@This()) void {
            const x: *T = @alignCast(@fieldParentPtr("counter", m));
            x.count += 1;
        }
    };
}

pub const Foo = struct {
    count: u32 = 0,
    counter: CounterMixin(Foo) = .{},  // 零位字段
};
// 使用方式:foo.counter.increment()

async/await Keywords Removed

async/await关键字已被移除

The
async
,
await
, and
@frameSize
have been removed. Async functionality will be provided via the standard library's new I/O interface.
zig
// ❌ REMOVED - no async/await keywords
async fn fetchData() ![]u8 { ... }
const result = await fetchData();

// ✅ Use std.Io interfaces or threads instead
async
await
@frameSize
已被移除。异步功能将通过标准库的新I/O接口提供。
zig
// ❌ 已移除 - 不再支持async/await关键字
async fn fetchData() ![]u8 { ... }
const result = await fetchData();

// ✅ 使用std.Io接口或线程替代

Arithmetic on undefined

对undefined值的算术操作

Operations on
undefined
that could trigger illegal behavior now cause compile errors:
zig
const a: u32 = 0;
const b: u32 = undefined;

// ❌ COMPILE ERROR in 0.15+
_ = a + b;  // error: use of undefined value here causes illegal behavior
对可能触发非法行为的
undefined
值进行操作现在会导致编译错误:
zig
const a: u32 = 0;
const b: u32 = undefined;

// ❌ 0.15+版本编译错误
_ = a + b;  // 错误:此处使用undefined值会导致非法行为

Lossy Integer to Float Coercion

整数到浮点数的有损转换

Compile error if integer cannot be precisely represented:
zig
// ❌ COMPILE ERROR in 0.15+
const val: f32 = 123_456_789;  // error: cannot represent precisely

// ✅ CORRECT - opt-in to floating-point rounding
const val: f32 = 123_456_789.0;
如果整数无法被精确表示为浮点数,将触发编译错误:
zig
// ❌ 0.15+版本编译错误
const val: f32 = 123_456_789;  // 错误:无法精确表示

// ✅ 正确写法 - 选择启用浮点数舍入
const val: f32 = 123_456_789.0;

Extended References (This Skill)

扩展参考(本技能)

详细的 API 参考和迁移指南请查阅以下文档:
文档路径内容
标准库 API 详解
references/stdlib-api-reference.md
ArrayList、HashMap、HTTP Client、Ed25519、Base64、JSON、@typeInfo、std.fmt 等完整 API 参考
迁移模式指南
references/migration-patterns.md
从 0.13/0.14 迁移到 0.15 的详细对照,包括 Writergate、ArrayList、Build System 等
生产级代码库
references/production-codebases.md
Sig(Solana)、ZML(AI)、Zeam(Ethereum)、Bun、Tigerbeetle 等项目学习指南,以及 0.15.x 兼容库列表
版本策略
VERSIONING.md
版本兼容性说明和更新策略
详细的 API 参考和迁移指南请查阅以下文档:
文档路径内容
标准库 API 详解
references/stdlib-api-reference.md
ArrayList、HashMap、HTTP Client、Ed25519、Base64、JSON、@typeInfo、std.fmt 等完整 API 参考
迁移模式指南
references/migration-patterns.md
从 0.13/0.14 迁移到 0.15 的详细对照,包括 Writergate、ArrayList、Build System 等
生产级代码库
references/production-codebases.md
Sig(Solana)、ZML(AI)、Zeam(Ethereum)、Bun、Tigerbeetle 等项目学习指南,以及 0.15.x 兼容库列表
版本策略
VERSIONING.md
版本兼容性说明和更新策略

快速查阅建议

快速查阅建议

  • 编写 HTTP 请求? → 查看
    references/stdlib-api-reference.md
    std.http.Client
    部分
  • ArrayList 报错? → 查看
    references/migration-patterns.md
    ArrayList Migration
    部分
  • 学习最佳实践? → 查看
    references/production-codebases.md
    中的 Sig 项目(Solana 验证器)
  • 寻找第三方库? → 查看
    references/production-codebases.md
    Smaller Learning Projects
    表格
  • 编写 HTTP 请求? → 查看
    references/stdlib-api-reference.md
    std.http.Client
    部分
  • ArrayList 报错? → 查看
    references/migration-patterns.md
    ArrayList Migration
    部分
  • 学习最佳实践? → 查看
    references/production-codebases.md
    中的 Sig 项目(Solana 验证器)
  • 寻找第三方库? → 查看
    references/production-codebases.md
    Smaller Learning Projects
    表格

References

参考资料

Official Documentation (0.15.2):
Community Resources (0.15.x):
Cookbook Recipe Categories (all tested on 0.15.x):
  • File System: read files, mmap, iterate directories
  • Cryptography: SHA-256, PBKDF2, Argon2
  • Network: TCP/UDP client/server
  • Web: HTTP GET/POST, HTTP server
  • Concurrency: threads, shared data, thread pools
  • Encoding: JSON, ZON, base64
  • Database: SQLite, PostgreSQL, MySQL
Production Zig Codebases (learn from real-world projects):
ProjectURLLearn From
Sighttps://github.com/Syndica/sigSolana validator in Zig - most relevant for this SDK!
Zeamhttps://github.com/blockblaz/zeamEthereum client in Zig - blockchain patterns
Bunhttps://github.com/oven-sh/bunJS runtime, async I/O, FFI, build system
Tigerbeetlehttps://github.com/tigerbeetle/tigerbeetleFinancial DB, deterministic execution, testing
Machhttps://github.com/hexops/machGame engine, graphics, memory management
Ghosttyhttps://github.com/ghostty-org/ghosttyTerminal emulator, cross-platform, GPU rendering
Zig Algorithmshttps://github.com/TheAlgorithms/ZigData structures, algorithms, idiomatic Zig
Key Sections in Release Notes:
Source Code & Development:
官方文档(0.15.2版本)
社区资源(0.15.x版本)
Cookbook示例分类(全部在0.15.x版本测试通过):
  • 文件系统:读取文件、mmap、遍历目录
  • 加密:SHA-256、PBKDF2、Argon2
  • 网络:TCP/UDP客户端/服务器
  • Web:HTTP GET/POST、HTTP服务器
  • 并发:线程、共享数据、线程池
  • 编码:JSON、ZON、base64
  • 数据库:SQLite、PostgreSQL、MySQL
生产级Zig代码库(从实际项目中学习):
项目链接学习点
Sighttps://github.com/Syndica/sig用Zig编写的Solana验证器 - 与本SDK最相关!
Zeamhttps://github.com/blockblaz/zeam用Zig编写的以太坊客户端 - 区块链模式
Bunhttps://github.com/oven-sh/bunJS运行时、异步I/O、FFI、构建系统
Tigerbeetlehttps://github.com/tigerbeetle/tigerbeetle金融数据库、确定性执行、测试
Machhttps://github.com/hexops/mach游戏引擎、图形学、内存管理
Ghosttyhttps://github.com/ghostty-org/ghostty终端模拟器、跨平台、GPU渲染
Zig Algorithmshttps://github.com/TheAlgorithms/Zig数据结构、算法、Zig惯用写法
发布说明中的关键章节
源码与开发

Version Compatibility Notes

版本兼容性说明

This skill targets Zig 0.15.x. If you're using a different version:
VersionDocumentationNotes
0.15.xThis skillCurrent stable, solana-zig uses 0.15.2
0.14.xhttps://ziglang.org/documentation/0.14.1/Old build.zig API, old std.io
0.13.xhttps://ziglang.org/documentation/0.13.0/ArrayList without allocator param
masterhttps://ziglang.org/documentation/master/Unstable, APIs may change daily
How to check your Zig version:
bash
zig version
本技能针对Zig 0.15.x版本。如果你使用其他版本:
版本文档说明
0.15.x本技能当前稳定版,solana-zig使用0.15.2版本
0.14.xhttps://ziglang.org/documentation/0.14.1/旧的build.zig API、旧的std.io
0.13.xhttps://ziglang.org/documentation/0.13.0/ArrayList不需要allocator参数
masterhttps://ziglang.org/documentation/master/不稳定版,API可能每日变更
如何检查你的Zig版本
bash
zig version

or for this project:

或针对当前项目:

./solana-zig/zig version

**When APIs differ from this skill**:
1. Check your actual Zig version
2. Consult version-specific documentation
3. Use compiler errors as guidance - Zig has excellent error messages
./solana-zig/zig version

**当API与本技能描述不符时**:
1. 检查你的实际Zig版本
2. 查阅对应版本的官方文档
3. 以编译器错误信息为指导 - Zig的错误信息非常完善