Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .autocorrectrc
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
file_types:
smd: markdown
shtml: html

# yaml-language-server: $schema=https://huacnlee.github.io/autocorrect/schema.json
rules:
space_word: 1
space_punctuation: 1
fullwidth: 1
fileTypes:
smd: markdown
shtml: html
context:
codeblock: 1
2 changes: 1 addition & 1 deletion content/contributing.smd
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Zig 中文社区是一个开放的组织,我们致力于推广 Zig 在中文
## [供稿方式]($heading.id('contribute'))

1. Fork 仓库 https://github.com/zigcc/zigcc.github.io
2. 在 `content/post` 内添加自己的文章(smd格式),文件命名为: `${YYYY}-${MM}-${DD}-${SLUG}.smd`
2. 在 `content/post` 内添加自己的文章(smd 格式),文件命名为: `${YYYY}-${MM}-${DD}-${SLUG}.smd`
3. 文件开始需要包含一些描述信息,例如:

```ziggy
Expand Down
12 changes: 6 additions & 6 deletions content/learn/coding-in-zig.smd
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ pub fn main() !void {
try stdout.print("Please enter a name: ", .{});
if (try stdin.readUntilDelimiterOrEof(&buf, '\n')) |line| {
var name = line;
// Windows平台换行以`\r\n`结束
// Windows 平台换行以 `\r\n` 结束
// 所以需要截取\r以获取控制台输入字符
if (builtin.os.tag == .windows) {
name = @constCast(std.mem.trimRight(u8, name, "\r"));
Expand Down Expand Up @@ -222,7 +222,7 @@ defer {

现在你可以忘掉我们的 `IntList` 和我们创建的通用替代方案了。Zig 标准库中有一个动态数组实现:`std.ArrayList(T)`。

它是相当标准的东西,但由于它如此普遍需要和使用的数据结构,值得看看它的实际应用:
它是相当标准的东西,但由于它如此普遍需要和使用的数据结构,值得看看它的实际应用

```zig
const std = @import("std");
Expand Down Expand Up @@ -459,7 +459,7 @@ zig build install -Doptimize=ReleaseSmall -Dtarget=x86_64-windows-gnu
除了默认的『安装』步骤外,可执行文件通常还会增加两个步骤:『运行』和『测试』。一个库可能只有一个『测试』步骤。对于基本的无参数即可运行的程序来说,只需要在构建文件的最后添加四行:

```zig
// 在这行代码后添加下面的代码: b.installArtifact(exe);
// 在这行代码后添加下面的代码b.installArtifact(exe);

const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
Expand Down Expand Up @@ -495,7 +495,7 @@ test "dummy build test" {

现在运行 `zig build test`时,应该会出现测试失败。如果你修复了测试,并再次运行 `zig build test`,你将不会得到任何输出。默认情况下,Zig 的测试运行程序只在失败时输出结果。如果你像我一样,无论成功还是失败,都想要一份总结,那就使用 `zig build test --summary all`。

这是启动和运行构建系统所需的最低配置。但是请放心,如果你需要构建你的程序,Zig 内置的功能大概率能覆盖你的需求。最后,你可以(也应该)在你的项目根目录下使用 `zig init`,让 Zig 为你创建一个文档齐全的 `build.zig` 文件。
这是启动和运行构建系统所需的最低配置。但是请放心如果你需要构建你的程序,Zig 内置的功能大概率能覆盖你的需求。最后,你可以(也应该)在你的项目根目录下使用 `zig init`,让 Zig 为你创建一个文档齐全的 `build.zig` 文件。

## [第三方依赖]($heading.id('third-party-dependencies'))

Expand Down Expand Up @@ -655,12 +655,12 @@ _ = b.addModule("calc", .{
要使用这一依赖关系,我们需要对 `build.zig` 进行一处修改:

```zig
// 将这些代码:
// 将这些代码
const calc_module = b.addModule("calc", .{
.root_source_file = b.path("calc/calc.zig"),
});

// 替换成:
// 替换成
const calc_dep = b.dependency("calc", .{.target = target,.optimize = optimize});
const calc_module = calc_dep.module("calc");
```
Expand Down
8 changes: 4 additions & 4 deletions content/learn/heap-memory.smd
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ fn allocLower(allocator: Allocator, str: []const u8) ![]const u8 {
}
```

上面的代码没问题。但以下用法不是:
上面的代码没问题。但以下用法不是

```zig
// 对于这个特定的代码,我们应该使用 std.ascii.eqlIgnoreCase
Expand Down Expand Up @@ -290,7 +290,7 @@ pub fn main() !void {
const T = std.heap.GeneralPurposeAllocator(.{});
var gpa = T{};

// 等同于:
// 等同于

var gpa = std.heap.GeneralPurposeAllocator(.{}){};
```
Expand Down Expand Up @@ -421,7 +421,7 @@ var larger = try self.allocator.alloc(i64, len * 2);
self.allocator.free(self.items);
```

将`items`复制到我们的 `larger` 切片中后, 添加最后一行`free`可以解决泄漏的问题。如果运行 `zig test learning.zig`,便不会再有错误。
将`items`复制到我们的 `larger` 切片中后添加最后一行`free`可以解决泄漏的问题。如果运行 `zig test learning.zig`,便不会再有错误。

## [ArenaAllocator]($heading.id('arena-allocator'))

Expand Down Expand Up @@ -504,7 +504,7 @@ defer list.deinit();
...
```

由于 `IntList` 接受的参数是 `std.mem.Allocator`, 因此我们不需要做什么改变。如果 `IntList`内部创建了自己的 `ArenaAllocator`,那也是可行的。允许在`ArenaAllocator`内部创建`ArenaAllocator`。
由于 `IntList` 接受的参数是 `std.mem.Allocator`,因此我们不需要做什么改变。如果 `IntList`内部创建了自己的 `ArenaAllocator`,那也是可行的。允许在`ArenaAllocator`内部创建`ArenaAllocator`。

最后举个简单的例子,我上面提到的 HTTP 服务器在响应中暴露了一个 `ArenaAllocator`。一旦发送了响应,它就会被清空。由于`ArenaAllocator`的生命周期可以预测(从请求开始到请求结束),因此它是一种高效的选择。就性能和易用性而言,它都是高效的。

Expand Down
6 changes: 3 additions & 3 deletions content/learn/language-overview-1.smd
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ pub const User = struct {

## [模块引用]($heading.id('module-reference'))

很少有程序是在没有标准库或外部库的情况下以单个文件编写的。我们的第一个程序也不例外,它使用 Zig 的标准库来进行打印输出。 Zig 的模块系统非常简单,只依赖于 `@import` 函数和 `pub` 关键字(使代码可以在当前文件外部访问)。
很少有程序是在没有标准库或外部库的情况下以单个文件编写的。我们的第一个程序也不例外,它使用 Zig 的标准库来进行打印输出。Zig 的模块系统非常简单,只依赖于 `@import` 函数和 `pub` 关键字(使代码可以在当前文件外部访问)。

> 以 `@` 开头的函数是内置函数。它们是由编译器提供的,而不是标准库提供的。

我们通过指定模块名称来引用它。 Zig 的标准库以 `std` 作为模块名。要引用特定文件,需要使用相对路径。例如,将 `User` 结构移动到它自己的文件中,比如 `models/user.zig`:
我们通过指定模块名称来引用它。Zig 的标准库以 `std` 作为模块名。要引用特定文件,需要使用相对路径。例如,将 `User` 结构移动到它自己的文件中,比如 `models/user.zig`:

```zig
// models/user.zig
Expand Down Expand Up @@ -295,7 +295,7 @@ const a = [_]i32{1, 2, 3, 4, 5};
const b = a[1..4];
```

在上述代码中, `b` 是一个长度为 3 的切片,并且是一个指向 `a` 的指针。但是因为我们使用编译时已知的值来对数组进行切片(即 `1` 和 `4`)所以长度 `3` 在编译时也是已知。 Zig 编译器能够分析出来这些信息,因此 `b` 不是一个切片,而是一个指向长度为 3 的整数数组的指针。具体来说,它的类型是 `*const [3]i32`。所以这个切片的示例被 Zig 编译器的强大推导能力挫败了。
在上述代码中, `b` 是一个长度为 3 的切片,并且是一个指向 `a` 的指针。但是因为我们使用编译时已知的值来对数组进行切片(即 `1` 和 `4`)所以长度 `3` 在编译时也是已知。Zig 编译器能够分析出来这些信息,因此 `b` 不是一个切片,而是一个指向长度为 3 的整数数组的指针。具体来说,它的类型是 `*const [3]i32`。所以这个切片的示例被 Zig 编译器的强大推导能力挫败了。

在实际代码中,切片的使用可能会多于数组。无论好坏,程序的运行时信息往往多于编译时信息。不过,在下面这个例子中,我们必须欺骗 Zig 编译器才能得到我们想要的示例:

Expand Down
2 changes: 1 addition & 1 deletion content/learn/pointers.smd
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ pub fn main() void {
}
```

我们最初的目标是通过`levelUp`函数将用户的`power`值增加 1 。我们已经让代码编译通过,但当我们打印`power`时,它仍然是原始值。虽然有点跳跃,但让我们修改代码,在 `main` 和 `levelUp` 中打印 `user`的地址:
我们最初的目标是通过`levelUp`函数将用户的`power`值增加 1。我们已经让代码编译通过,但当我们打印`power`时,它仍然是原始值。虽然有点跳跃,但让我们修改代码,在 `main` 和 `levelUp` 中打印 `user`的地址:

```zig
pub fn main() void {
Expand Down
4 changes: 2 additions & 2 deletions content/learn/stack-memory.smd
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ levelUp: user -> ------------- (id: 1043368ec) |
-------------
```

`levelUp` 紧接在 `main` 之后是有原因的:这是我们的简化版调用栈。当我们的程序启动时,`main` 及其局部变量被推入调用栈。当 `levelUp` 被调用时,它的参数和任何局部变量都会被添加到调用栈上。重要的是,当 `levelUp` 返回时,它会从栈中弹出。 在 `levelUp` 返回并且控制权回到 `main` 后,我们的调用栈如下所示:
`levelUp` 紧接在 `main` 之后是有原因的:这是我们的简化版调用栈。当我们的程序启动时,`main` 及其局部变量被推入调用栈。当 `levelUp` 被调用时,它的参数和任何局部变量都会被添加到调用栈上。重要的是,当 `levelUp` 返回时,它会从栈中弹出。在 `levelUp` 返回并且控制权回到 `main` 后,我们的调用栈如下所示:

```
main: user -> ------------- (id: 1043368d0)
Expand Down Expand Up @@ -128,7 +128,7 @@ User 1 has power of 10
User 2 has power of 20
```

但实际上:
但实际上

```bash
User 2 has power of 20
Expand Down
4 changes: 2 additions & 2 deletions content/learn/style-guide.smd
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

> 原文地址:<https://www.openmymind.net/learning_zig/style_guide>

本小节的主要内容是介绍 Zig 编译器强制遵守的 2 条规则,以及 Zig 标准库的命名惯例(naming convention)。
本小节的主要内容是介绍 Zig 编译器强制遵守的 2 条规则,以及 Zig 标准库的命名惯例 (naming convention)。

## [未使用变量 Unused Variable]($heading.id('unused-variable'))

Expand All @@ -27,7 +27,7 @@ fn add(a: i64, b: i64) i64 {
}
```

第一个编译错误,源自于`sum`是一个未使用的本地常量。第二个编译错误,在于在函数`add`的所有形参中,`b`是一个未使用的函数参数。对于这段代码来说,它们是比较明显的漏洞。但是在实际编程中,代码中包含未使用变量和函数形参并非完全不合理。在这种情况下,我们可以通过将未使用变量赋值给`_`(下划线)的方法,避免编译器报错:
第一个编译错误,源自于`sum`是一个未使用的本地常量。第二个编译错误,在于在函数`add`的所有形参中,`b`是一个未使用的函数参数。对于这段代码来说,它们是比较明显的漏洞。但是在实际编程中,代码中包含未使用变量和函数形参并非完全不合理。在这种情况下,我们可以通过将未使用变量赋值给`_`(下划线)的方法,避免编译器报错

```zig
const std = @import("std");
Expand Down
6 changes: 3 additions & 3 deletions content/monthly/202209.smd
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
在 9/10 号左右,在 Twitter 上牵起了一小波关于 Zig VS Rust
的小火花,以至于最后 Zig 创始人 Andrew Kelley
[发推](https://twitter.com/andy_kelley/status/1568679389113757698)表示
Let us exist。这里稍微整理下这件事情的过程: 本次事件主要涉及两个人:
Let us exist。这里稍微整理下这件事情的过程:本次事件主要涉及两个人:

- Rust 核心贡献者: Patrick Walton
- Zig 社区 VP: Loris Cro
- Rust 核心贡献者:Patrick Walton
- Zig 社区 VP:Loris Cro

## [时间线]($heading.id('timeline'))

Expand Down
2 changes: 1 addition & 1 deletion content/monthly/202308.smd
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ Andrew 关于构建系统的视频,[B

[Wrap your NIF with Zig](https://rbino.com/posts/wrap-your-nif-with-zig/)
NIF 是 Elixir 中进行 FFI 调用的方式,如果用原生 C
接口来用,会需要写很多胶水代码, 作者这里用 comptime 特性来定义了一个
接口来用,会需要写很多胶水代码,作者这里用 comptime 特性来定义了一个
`make_nif_wrapper` 来简化 NIF 的实现,这个技巧在与 C
项目交互时十分有用。

Expand Down
6 changes: 3 additions & 3 deletions content/monthly/202403.smd
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Autodoc,之前的实现问题很多。比如:
wasm 就可以调用

- 功能更强,因为新设计方案不再处理
ZIR,而是直接处理源文件,这意味着它拥有100%
ZIR,而是直接处理源文件,这意味着它拥有 100%
的信息,不需要向后拼凑任何东西。

- sources.tar 文件经 HTTP 层解压后,直接进入 wasm 模块的内存。使用
Expand Down Expand Up @@ -151,7 +151,7 @@ errdefer comptime unreachable
```

文中称这个是 Zig 的巅峰用法😅, `errdefer unreachable`
还比较好理解,即在执行出错时,执行 unreachable ,加上 comptime 呢?
还比较好理解,即在执行出错时,执行 unreachable,加上 comptime 呢?

其实这是阻止 Zig
编译器生产错误处理的代码,即在编译时期保证下面的逻辑不会出错,确实用的很巧妙!一个简单的例子:
Expand Down Expand Up @@ -214,7 +214,7 @@ test.zig:4:23: error: reached unreachable code
+}
```

可以看到, 这么修改后,就可以保证 `map.deinit(allocator)`
可以看到,这么修改后,就可以保证 `map.deinit(allocator)`
语句之前没有错误可能产生!读者可以细细品味一下这个用法。

另一个小技巧是 errdefer 竟然支持错误捕获,即下面这种用法:
Expand Down
2 changes: 1 addition & 1 deletion content/monthly/202404.smd
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Zig 生态的发展是十分关键的一步,试想一个项目用到的依赖
这个版本解决了,用户可以基于 Step
构成的有向无环图来编译自己的项目,不需要再折腾
CMake、Makefile、Vcpkg、Git submodule 等工具,所有的依赖使用 zon
来管理即可。 读者如果对 Zig 构建系统还不熟悉,可以参考:
来管理即可。读者如果对 Zig 构建系统还不熟悉,可以参考:

- 官方文档:[Zig Build System](https://ziglang.org/learn/build-system/)
- Zig 升级:
Expand Down
2 changes: 1 addition & 1 deletion content/monthly/202405.smd
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Zig,这是个不错的经验参考。
- 十分简洁,import 返回的是一个 struct,和其他变量一样使用
- 与 C 无缝交换,
- 具有 Result 效果的错误处理
- 唯一缺失的就是『接口』,但这一点并不是很关键,就像在 C里也没有,但是 C
- 唯一缺失的就是『接口』,但这一点并不是很关键,就像在 C 里也没有,但是 C
可以做任何事

### [Zig's New CLI Progress Bar Explained]($heading.id('zigs-new-cli-progress-bar-explained'))
Expand Down
6 changes: 3 additions & 3 deletions content/monthly/202406.smd
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
## [重大事件]($heading.id('major-events'))

2024-06-07,0.13.0 发布,历时不足 2 个月,有 73 位贡献者,一共进行了 415
次提交! 这是一个相对较短的发布周期,主要原因是工具链升级,例如升级到
次提交!这是一个相对较短的发布周期,主要原因是工具链升级,例如升级到
[LLVM
18](https://ziglang.org/download/0.13.0/release-notes.html#LLVM-18)。

Expand All @@ -36,7 +36,7 @@ const map = std.StaticStringMap(T).initComptime(kvs_list);
[原文链接](https://www.openmymind.net/Leveraging-Zigs-Allocators/)

老朋友 openmymind 的又一篇好文章:如何利用 Zig 的 Allocator
来实现请求级别的内存分配。 Zig Allocator
来实现请求级别的内存分配。Zig Allocator
的最佳应用。[这里](/post/2024-06-16-leveraging-zig-allocator/)它的中文翻译。

``` zig
Expand Down Expand Up @@ -107,7 +107,7 @@ fn run(worker: *Worker) void {
[原文链接](https://ludwigabap.bearblog.dev/zig-vs-rust-at-work-the-choice-we-made/)

这篇文章作者描述了所在公司在改造老 C/C++ 项目时,为什么选择了 Zig 而不是
Rust。 重写的项目运行在多个平台上(Web、移动端、VR
Rust。重写的项目运行在多个平台上(Web、移动端、VR
设备),因此最靠谱的方案就是暴露一个 C API,然后通过 FFI
来调用。在做决策时,重点关注以下两点:

Expand Down
Loading