|
| 1 | +#+TITLE: 202308 | 0.11 正式发布 |
| 2 | +#+DATE: 2023-09-03T19:38:04+0800 |
| 3 | +#+LASTMOD: 2023-09-03T21:53:06+0800 |
| 4 | +* 0.11 release note |
| 5 | +** Peer Type Resolution Improvements |
| 6 | +对等类型解析算法得到改进,下面是一些在 0.10 中不能解析,但在 0.11 中可以解析的例子: |
| 7 | +| Peer Types | Resolved Type | |
| 8 | +| [:s]const T, []T | []const T | |
| 9 | +| E!*T, ?*T | E!?*T | |
| 10 | +| [*c]T, @TypeOf(null) | [*c]T | |
| 11 | +| ?u32, u8 | ?u32 | |
| 12 | +| [2]u32, struct { u32, u32 } | [2]u32 | |
| 13 | +| *const @TypeOf(.{}), []const u8 | []const u8 | |
| 14 | + |
| 15 | +而且现在使用 =@intCast= 这类 builtin 都只接受一个参数,目前类型根据上下文自动推断出来。 |
| 16 | +** Multi-Object For Loops |
| 17 | +可以同时对多个对象进行遍历: |
| 18 | +#+begin_src zig |
| 19 | +// 之前 |
| 20 | +for (input) |x, i| { |
| 21 | + output[i] = x * 2; |
| 22 | +} |
| 23 | + |
| 24 | +// 现在 |
| 25 | +for (input, 0..) |x, i| { |
| 26 | + output[i] = x * 2; |
| 27 | +} |
| 28 | +#+end_src |
| 29 | +** @min and @max |
| 30 | +主要有两个改动: |
| 31 | +1. 这两个 builtin 现在支持任意多个参数 |
| 32 | +2. 返回的类型,会尽可能的紧凑 |
| 33 | +#+begin_src zig |
| 34 | +test "@min/@max refines result type" { |
| 35 | + const x: u8 = 20; // comptime-known |
| 36 | + var y: u64 = 12345; |
| 37 | + // Since an exact bound is comptime-known, the result must fit in a u5 |
| 38 | + comptime assert(@TypeOf(@min(x, y)) == u5); |
| 39 | + |
| 40 | + var x_rt: u8 = x; // runtime-known |
| 41 | + // Since one argument to @min is a u8, the result must fit in a u8 |
| 42 | + comptime assert(@TypeOf(@min(x_rt, y)) == u8); |
| 43 | +} |
| 44 | +#+end_src |
| 45 | +** @inComptime |
| 46 | +新加的 builtin,用于判断执行是否在 comptime 环境下执行: |
| 47 | +#+begin_src zig |
| 48 | +const global_val = blk: { |
| 49 | + assert(@inComptime()); |
| 50 | + break :blk 123; |
| 51 | +}; |
| 52 | + |
| 53 | +comptime { |
| 54 | + assert(@inComptime()); |
| 55 | +} |
| 56 | + |
| 57 | +fn f() u32 { |
| 58 | + if (@inComptime()) { |
| 59 | + return 1; |
| 60 | + } else { |
| 61 | + return 2; |
| 62 | + } |
| 63 | +} |
| 64 | + |
| 65 | +test "@inComptime" { |
| 66 | + try expectEqual(true, comptime @inComptime()); |
| 67 | + try expectEqual(false, @inComptime()); |
| 68 | + try expectEqual(@as(u32, 1), comptime f()); |
| 69 | + try expectEqual(@as(u32, 2), f()); |
| 70 | +} |
| 71 | +#+end_src |
| 72 | +** 类型转化相关 builtin 的重命名 |
| 73 | +之前 =@xToY= 形式的 builtin 现在已经改成了 =@yFromX= ,这样的主要好处是便于阅读(从右向左),这是[[https://github.com/ziglang/zig/issues/6128][草案]]。 |
| 74 | +** Tuple 类型声明 |
| 75 | +现在可以直接用无 field 名字的 struct 来声明 tuple 类型: |
| 76 | +#+begin_src zig |
| 77 | +test "tuple declarations" { |
| 78 | + const T = struct { u32, []const u8 }; |
| 79 | + var t: T = .{ 1, "foo" }; |
| 80 | + try expect(t[0] == 1); |
| 81 | + try expectEqualStrings(t[1], "foo"); |
| 82 | + |
| 83 | + var mul = t ** 3; |
| 84 | + try expect(@TypeOf(mul) != T); |
| 85 | + try expect(mul.len == 6); |
| 86 | + try expect(mul[2] == 1); |
| 87 | + try expectEqualStrings(mul[3], "foo"); |
| 88 | + |
| 89 | + var t2: T = .{ 2, "bar" }; |
| 90 | + var cat = t ++ t2; |
| 91 | + try expect(@TypeOf(cat) != T); |
| 92 | + try expect(cat.len == 4); |
| 93 | + try expect(cat[2] == 2); |
| 94 | + try expectEqualStrings(cat[3], "bar"); |
| 95 | +} |
| 96 | +#+end_src |
| 97 | + |
| 98 | +之前只能用 =std.meta.Tuple= 函数来定义: |
| 99 | +#+begin_src diff |
| 100 | +- const testcases = [_]std.meta.Tuple(&[_]type{ []const u8, []const u8, bool }){ |
| 101 | ++ const testcases = [_]struct { []const u8, []const u8, bool }{ |
| 102 | +#+end_src |
| 103 | +** 排序 |
| 104 | +现在排序算法分布两类: |
| 105 | +- 稳定,blocksort 算法 |
| 106 | +- 不稳定,[[https://github.com/ziglang/zig/pull/15412][pdqsort]] 算法,它结合了随机快速排序的快速平均情况和堆排序的快速最坏情况。 |
| 107 | +与堆排的快速最差情况相结合,同时在具有特定模式的输入上达到线性时间。 |
| 108 | +** Stack Unwinding |
| 109 | +Zig 之前依赖 [[https://en.wikipedia.org/wiki/Call_stack#Stack_and_frame_pointers][frame pointer]] 来做堆栈回卷,但它本身有些代价,因此线上环境可能会通过 =-fomit-frame-pointer= 将其禁用掉。 |
| 110 | + |
| 111 | +为了在这种情况下依然能够获取 panic 是的堆栈信息,Zig 现在支持了通过 DWARF unwind tables 和 MachO compact unwind information 来会恢复堆栈,详见:[[https://github.com/ziglang/zig/pull/15823][#15823]]。 |
| 112 | +** 包管理 |
| 113 | +0.11 首次正式引入了包管理器,具体解释可以参考:[[https://en.liujiacai.net/2023/04/13/zig-build-system/][Zig Build System]],而且很重要一点,step 之间可以[[https://ziglang.org/download/0.11.0/release-notes.html#Steps-Run-In-Parallel][并发执行]], |
| 114 | +** Bootstrapping |
| 115 | +C++ 实现的 Zig 编译器已经被彻底移除,这意味着 =-fstage1= 不再生效,Zig 现在只需要一个 2.4M 的 WebAssembly 文件和一个 C 编辑器即可,工作细节可以参考:[[https://ziglang.org/news/goodbye-cpp/][Goodbye to the C++ Implementation of Zig]]。 |
| 116 | +** 代码生成 |
| 117 | +虽然 Zig 编译器现在还是主要使用 LLVM 来进行代码生成,但在这次发布中,其他几个后端也有了非常大的进步: |
| 118 | +1. C 后端,行为测试通过 98%,而且生成的 C 代码兼容微软的 MSVC,用在了 bootstrapping 中 |
| 119 | +2. x86 后端,行为测试通过 88% |
| 120 | +3. aarch64 后端,刚开始 |
| 121 | +4. WebAssembly 后端,行为测试通过 86%, |
| 122 | +5. SPIR-V 后端,SPIR-V 是在 GPU 上运行的着色器(shader)和内核的字节码表示法。目前,Zig 的 SPIR-V 后端专注于为 OpenCL 内核生成代码,不过未来可能也会支持兼容 Vulkan 的着色器。 |
| 123 | +** 增量编译 |
| 124 | +虽然这仍是一个高度 WIP 的功能,但这一版本周期中的许多改进为编译器的增量编译功能铺平了道路。其中最重要的是 [[https://github.com/ziglang/zig/pull/15569][InternPool]]。Zig 用户大多看不到这一改动,但它为编译器带来了许多好处,其中之一就是我们现在更接近增量编译了。增量编译将是 0.12.0 发布周期的重点。 |
| 125 | +* 观点/教程 |
| 126 | +* 项目/工具 |
| 127 | +* [[https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-07-01..2023-08-01][Zig 语言更新]] |
0 commit comments