@@ -16,16 +16,16 @@ Zig 目前默认使用 x86 后端,调试编译速度提高了 **5** 倍;aarc
1616
1717## 系统最低版本要求
1818
19- | 操作系统(Operating System) | 最低版本要求 (Minimum Version) |
20- | :------------------------- | :-----------------------------: |
21- | Dragonfly BSD | 6.0 |
22- | FreeBSD | 14.0 |
23- | Linux | 5.10 |
24- | NetBSD | 10.1 |
25- | OpenBSD | 7.6 |
26- | macOS | 13.0 |
27- | Solaris | 11 |
28- | Windows | 10 |
19+ | 操作系统(Operating System) | 最低版本要求(Minimum Version) |
20+ | :--------------------------- | :- -----------------------------: |
21+ | Dragonfly BSD | 6.0 |
22+ | FreeBSD | 14.0 |
23+ | Linux | 5.10 |
24+ | NetBSD | 10.1 |
25+ | OpenBSD | 7.6 |
26+ | macOS | 13.0 |
27+ | Solaris | 11 |
28+ | Windows | 10 |
2929
3030## 语言变动
3131
@@ -157,7 +157,7 @@ pub const Foo = struct {
157157};
158158```
159159
160- 替代写法基于前述的命名空间思想:其实** 恰当的命名空间划分是好事** 。Mixins 也可以用命名空间来组织。比如把 ` incrementCounter ` 和 ` resetCounter ` 名称中的 “counter” 前缀直接变成一个嵌套字段,这样 ` foo.counter.increment() ` 替代 ` foo.incrementCounter() ` ,语义更直观。
160+ 替代写法基于前述的命名空间思想:其实** 恰当的命名空间划分是好事** 。Mixins 也可以用命名空间来组织。比如把 ` incrementCounter ` 和 ` resetCounter ` 名称中的“counter”前缀直接变成一个嵌套字段,这样 ` foo.counter.increment() ` 替代 ` foo.incrementCounter() ` ,语义更直观。
161161
162162实现方式可利用零位字段(zero-bit field)和 ` @fieldParentPtr ` :
163163
@@ -182,13 +182,12 @@ pub const Foo = struct {
182182};
183183```
184184
185- 这样写后,调用就是 ` foo.counter.increment() ` ,不再是 ` foo.incrementCounter() ` 。通过零位字段成功将 mixin “命名空间化”。
185+ 这样写后,调用就是 ` foo.counter.increment() ` ,不再是 ` foo.incrementCounter() ` 。通过零位字段成功将 mixin“命名空间化”。
186186
187187实际上,这比以前更灵活,也能让混入体包含如字段等更多内容。比如本例中甚至可以将 ` count ` 字段本身都移到 ` CounterMixin ` 内部(虽然这种场景下其实不算 mixin,因为只剩状态本身)。
188188
189189更重要的是,如果某些复杂混入需要额外状态,这种办法也能避免每个站点都重复字段声明,维护起来更方便。
190190
191-
192191### 移除 async 和 await 关键字
193192
194193` async ` 和 ` await ` 关键字已被移除,` @frameSize ` 也已删除。
@@ -292,7 +291,7 @@ All 1 tests passed.
292291
293292Zig 0.15.x 开始规范 ` undefined ` 在不同场景下的行为,特别是在参与算术运算时的规则。简言之,只有那些永远不会导致非法行为的运算符才允许 ` undefined ` 作为操作数。其它情况,若操作数为 ` undefined ` ,将触发非法行为(运行时报错)或编译时报错。
294293
295- 通用的最佳实践是:* 始终避免对 ` undefined ` 进行任何操作 * 。这样一来,这一语言变更(及未来相关变动)基本不会影响你的代码。如果你受到了此项语言变更影响,你可能会在原本可以编译的代码上见到类似的报错:
294+ 通用的最佳实践是:_ 始终避免对 ` undefined ` 进行任何操作 _ 。这样一来,这一语言变更(及未来相关变动)基本不会影响你的代码。如果你受到了此项语言变更影响,你可能会在原本可以编译的代码上见到类似的报错:
296295
297296``` zig arith-on-undefined.zig
298297const a: u32 = 0;
@@ -368,7 +367,7 @@ All 1 tests passed.
368367[ Systems Distributed 2025 演讲:Don't Forget To Flush] ( https://www.youtube.com/watch?v=f30PceqQWko )
369368
370369- 老接口是泛型的,污染了包含它们的结构体,并导致所有相关函数都要用 ` anytype ` 泛型。新接口是具体类型。
371- - 额外好处:类型具体化后,API 不容易直接作用于网络流、文件句柄或内存缓冲区,使代码更加可复用。例如更新后的 ` http.Server ` 不再依赖 ` std.net ` ,而是仅操作流。
370+ - 额外好处:类型具体化后,API 不容易直接作用于网络流、文件句柄或内存缓冲区,使代码更加可复用。例如更新后的 ` http.Server ` 不再依赖 ` std.net ` ,而是仅操作流。
372371- 老接口传递错误,但没有专用错误集合(error set),造成流的错误和 ` anyerror ` 类似。新接口为每个函数定义了明确的 error set,每个 error 都有可操作意义。
373372- 新接口将缓冲区集成进接口本身,而不再用单独的 "BufferedReader"/"BufferedWriter" 抽象。这样对优化器更加友好,特别是在 debug 模式下。
374373- 新接口支持诸如向量、填充(splatting)、直接文件传输(fd-to-fd)等高级特性,这些可以在读写器图(graph)中传递,减少系统调用、内存带宽和 CPU 使用率。
@@ -405,7 +404,7 @@ while (reader.takeDelimiterExclusive('\n')) |line| {
405404和其他语言的流实现相比,Zig 的流还新增了如下独特概念:
406405
407406- 读取时丢弃(discarding):可高效跳过数据。例如解压流在被请求丢弃大量数据时,可以直接跳过整个 frame。
408- - 写入时填充(splatting):等同逻辑上的 ` memset ` ,能在管道中无数据拷贝直接传递,将 O(M* N) 操作变成 O(M),有时(比如写入零)还能优化到直接 seek 跳过。
407+ - 写入时填充(splatting):等同逻辑上的 ` memset ` ,能在管道中无数据拷贝直接传递,将 O(M\ * N) 操作变成 O(M),有时(比如写入零)还能优化到直接 seek 跳过。
409408- 写入时传送整个文件:支持 I/O 管道在操作系统支持时直接 fd-to-fd 拷贝文件。
410409- 用户负责提供缓冲区,流实现决定最小缓冲区大小,等于把部分状态从实现转移到用户所提供的 buffer 上。
411410
@@ -809,19 +808,19 @@ try stack.appendSliceBounded(initial_stack);
809808- std.fmt.fmtDuration -> {D}
810809- std.fmt.fmtDurationSigned -> {D}
811810- std.fmt.Formatter -> std.fmt.Alt
812- - 现在需显式指定 context 类型
813- - 无 fmt 字符串参数
811+ - 现在需显式指定 context 类型
812+ - 无 fmt 字符串参数
814813- std.fmt.format -> std.Io.Writer.print
815814- std.io.GenericReader -> std.Io.Reader
816815- std.io.GenericWriter -> std.Io.Writer
817816- std.io.AnyReader -> std.Io.Reader
818817- std.io.AnyWriter -> std.Io.Writer
819818- 删除 std.io.SeekableStream
820- - 请用 * std.fs.File.Reader、* std.fs.File.Writer 或具体的 std.ArrayListUnmanaged,根据场景选取实现方式
819+ - 请用 * std.fs.File.Reader、* std.fs.File.Writer 或具体的 std.ArrayListUnmanaged,根据场景选取实现方式
821820- 删除 std.io.BitReader
822- - 不建议此层面抽象位读取,会妨碍热循环的性能优化,请与流实现紧密耦合
821+ - 不建议此层面抽象位读取,会妨碍热循环的性能优化,请与流实现紧密耦合
823822- 删除 std.io.BitWriter
824- - 同上
823+ - 同上
825824- 删除 std.Io.LimitedReader
826825- 删除 std.Io.BufferedReader
827826- 删除 std.fifo
@@ -879,7 +878,7 @@ Zig 0.14.0 提供了用于内置模糊测试 fuzzer 的实验性 Web 界面。
879878
880879Web 界面本身主要显示所有构建步骤及其状态,同时有按钮可手动触发重新构建(所以可以作为 ` zig build --watch` 流程的替代方式)。如果使用 ` --fuzz` ,则会暴露 [Fuzzer](https://ziglang.org/download/0.15.1/release-notes.html#Fuzzer) 相关界面,其内容与 0.14.0 基本一致。
881880
882- 此外,Web 界面新增了 “时间报告” 功能。只需为 ` zig build` 传递 ` --time-report` ,即可在 Web 界面上展开查看构建图中各步骤的耗时信息。尤其是每个 ` std.Build.Step.Compile` ,都会有详细的子阶段统计:Zig 编译器各部分的快慢情况,以及哪些文件/声明在语义分析、生成机器码、链接阶段消耗的时间最多。
881+ 此外,Web 界面新增了“时间报告”功能。只需为 ` zig build` 传递 ` --time-report` ,即可在 Web 界面上展开查看构建图中各步骤的耗时信息。尤其是每个 ` std.Build.Step.Compile` ,都会有详细的子阶段统计:Zig 编译器各部分的快慢情况,以及哪些文件/声明在语义分析、生成机器码、链接阶段消耗的时间最多。
883882
884883! [](https://ziglang.org/download/0.15.1/release-notes/build-webui.png)
885884
@@ -889,7 +888,7 @@ Web 界面本身主要显示所有构建步骤及其状态,同时有按钮可
889888
890889如果本次编译用到了 LLVM 后端,还会额外提供 LLVM pass 分阶段的耗时信息。
891890
892- # # Compiler
891+ # # Compiler
893892
894893# ## x86 后端
895894
@@ -899,7 +898,7 @@ Web 界面本身主要显示所有构建步骤及其状态,同时有按钮可
899898
900899启用自实现 x86_64 后端后,你将可以直接感受到 Zig 项目过去几年投入的成果:编译速度显著提升——大多数场景下比 LLVM 快了大约 5 倍。** 而这还只是开始** ;自实现 x86_64 后端是专为 [增量编译](https://ziglang.org/download/0.15.1/release-notes.html#Incremental-Compilation) 而设计的,这项功能足够稳定时,预计还会有极大加速。极致的编译速度一直是 Zig 项目的核心目标之一,我们已经默默推进多年,这次发布是阶段性成果的集中体现。
901900
902- 使用自实现 x86 后端,还能避免受上游 LLVM Bug 的影响(目前我们[正在跟踪 60 多个相关 Bug](https://github.com/ziglang/zig/issues? q=is%3Aissue%20state%3Aopen%20label%3Abackend-llvm%20label%3Aupstream))。事实上,自实现 x86 后端在我们的 “行为测试集” 上,已能通过比 LLVM 后端更多的用例(1984/2008,相比 LLVM 的 1977/2008)。换句话说,该后端对 Zig 语言的实现更为完整和准确。
901+ 使用自实现 x86 后端,还能避免受上游 LLVM Bug 的影响(目前我们[正在跟踪 60 多个相关 Bug](https://github.com/ziglang/zig/issues? q=is%3Aissue%20state%3Aopen%20label%3Abackend-llvm%20label%3Aupstream))。事实上,自实现 x86 后端在我们的“行为测试集”上,已能通过比 LLVM 后端更多的用例(1984/2008,相比 LLVM 的 1977/2008)。换句话说,该后端对 Zig 语言的实现更为完整和准确。
903902
904903当然,目前自实现 x86 后端本身也还[存在部分缺陷和 Bug](https://github.com/ziglang/zig/issues? q=is%3Aissue%20state%3Aopen%20label%3Abackend-self-hosted%20label%3Aarch-x86_64)。如果你遇到了相关问题,可以通过命令行参数 ` -fllvm` ,或在创建 ` std.Build.Step.Compile` 时设置 ` .use_llvm = true` ,将 Debug 编译切换回 LLVM 后端。此外,当前自实现 x86 后端生成的机器码在性能上[略慢于 LLVM 后端](https://github.com/ziglang/zig/issues/24144)。
905904
@@ -937,7 +936,7 @@ Zig 编译器自设计之初就考虑到了并行化。通过让编译的不同
937936
938937- 选择 ` full` 时,UBSan 运行时会被编译并链接进你的程序,遇到未定义行为时提供更详尽的错误信息,但相应代码体积会略大。
939938- 选择 ` trap` 时,会插入陷阱指令,触发未定义行为时进程会收到 ` SIGILL` ,但是代码体积更小。
940- 如未显式指定,默认模式由构建模式决定。
939+ 如未显式指定,默认模式由构建模式决定。
941940
942941对于 [zig cc](https://ziglang.org/download/0.15.1/release-notes.html#zig-cc),在已有的 ` -fsanitize=undefined` 外,现在也能理解 ` -fsanitize-trap=undefined` ,与 ` zig build-exe` 上的 ` -fsanitize-c=trap` 基本等价。
943942
@@ -951,7 +950,7 @@ Zig 编译器自设计之初就考虑到了并行化。通过让编译的不同
951950
952951使用构建系统时,可通过新版 ` std.Build` API,在调用 ` std.Build.addTest` 时传递 ` emit_object` 选项,这样返回的 ` Step.Compile` 会生成对象文件。这个对象文件和其他对象一样,可以被安装用于外部使用,或直接链接到其他 build 步骤。不过注意:启用此功能后,build runner 与 test runner 不会直接通信,退回到默认的 ` zig test` 方式(即用 stderr 报告测试失败)。所以如果你用到这个特性,可能还需自定义 test runner,让它能与外部测试框架协作。
953952
954- # ## Zig Init
953+ # ## Zig Init
955954
956955` zig init` 命令在本版本中配备了新版项目模板。
957956
@@ -984,4 +983,4 @@ Zig 依然有[已知 bug](https://github.com/ziglang/zig/issues?q=is%3Aopen+is%3
984983
985984即使使用 Zig 0.15.x,在较复杂的项目中工作,也可能需要你主动参与到开发流程当中,一起反馈和解决问题。
986985
987- 当 Zig 进入 1.0.0 正式版后,Tier 1 支持将会增加专门的 bug 管理政策作为强制要求。
986+ 当 Zig 进入 1.0.0 正式版后,Tier 1 支持将会增加专门的 bug 管理政策作为强制要求。
0 commit comments