diff --git a/.github/workflows/autocorrect.yml b/.github/workflows/autocorrect.yml new file mode 100644 index 00000000..b4c17136 --- /dev/null +++ b/.github/workflows/autocorrect.yml @@ -0,0 +1,23 @@ +name: AutoCorrect CI + +on: + pull_request: + workflow_dispatch: + +jobs: + autocorrect: + runs-on: ubuntu-latest + steps: + - name: Check source code + uses: actions/checkout@v4 + + - name: AutoCorrect + uses: huacnlee/autocorrect-action@v2 + + - name: Review Dog + if: failure() + uses: huacnlee/autocorrect-action@v2 + env: + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + reviewdog: true diff --git a/README.md b/README.md index 77b4c970..ed932088 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,6 @@ bun run build // 构建产物 bun run preview // 运行预览 ``` -注意:本文档所使用的构建工具为 [bunjs](https://bun.sh/),在提交时请勿将其他nodejs的包管理工具的额外配置文件添加到仓库中。 +注意:本文档所使用的构建工具为 [bunjs](https://bun.sh/),在提交时请勿将其他 nodejs 的包管理工具的额外配置文件添加到仓库中。 > 如需要更新依赖,请参照此处 [Lockfile](https://bun.sh/docs/install/lockfile) 先设置 git 使用 bun 来 diff 文件! diff --git a/TODO.md b/TODO.md index ef29abc6..673cef44 100644 --- a/TODO.md +++ b/TODO.md @@ -1 +1 @@ -- 浮点的optimized说明,和关于向量浮点reduce的情况 +- 浮点的 optimized 说明,和关于向量浮点 reduce 的情况 diff --git a/course/about.md b/course/about.md index 9b1e6ebd..adfa5424 100644 --- a/course/about.md +++ b/course/about.md @@ -25,6 +25,6 @@ showVersion: false ::: info 🅿️ 提示 -本文档所使用的构建工具为 [bunjs](https://bun.sh/),在提交时请勿将其他nodejs的包管理工具的额外配置文件添加到仓库中。 +本文档所使用的构建工具为 [bunjs](https://bun.sh/),在提交时请勿将其他 nodejs 的包管理工具的额外配置文件添加到仓库中。 ::: diff --git a/course/advanced/assembly.md b/course/advanced/assembly.md index 10e5dd24..87bde2b6 100644 --- a/course/advanced/assembly.md +++ b/course/advanced/assembly.md @@ -17,7 +17,7 @@ outline: deep ::: info 🅿️ 提示 -对于 x86 和 x86_64 ,当前汇编语法为 AT&T 语法,而不是更流行的 Intel 语法。这是由于技术限制,汇编解析由LLVM提供,其对 Intel 语法的支持存在 bug 且测试​​结果并不理想。 +对于 x86 和 x86_64,当前汇编语法为 AT&T 语法,而不是更流行的 Intel 语法。这是由于技术限制,汇编解析由 LLVM 提供,其对 Intel 语法的支持存在 bug 且测试​​结果并不理想。 在未来的某一天 Zig 可能有自己的汇编器。这将使汇编能够更加无缝地集成到语言中,并与流行的 Nasm 语法兼容。 @@ -68,7 +68,7 @@ asm volatile ("assembly code" ); ``` -结构大体是这样的: +结构大体是这样的: ```asm # 别忘记三个冒号,即便对应的部分不存在也需要有冒号 @@ -79,7 +79,7 @@ AssemblerTemplate ``` 1. 首先是一个内联汇编的语句,但它和普通的内联语句不同,它可以使用“占位符”,类似`%[value]`,这就是一个占位符,以 `%` 开头,如果需要使用寄存器,则需要使用两个 `%` ,例如使用 CR3 寄存器就是 `%%cr3`。 -2. 之后是一个输出位置,它表示你需要将值输出到哪里,也可以没有返回值,例如上方的示例中 `[ret] "={rax}" (-> usize)` 代表我们使用 `[ret]` 标记了返回值,并且返回值就是 rax 寄存器中的值,其后的 `(-> usize)` 代表我们整个内联汇编表达式需要返回一个值,当然这里如果是一个变量,就会将rax寄存器的值通过`[ret]`标记绑定到变量上。(注意,此处的 `=` 代表只能进行写入操作数,属于是一个约束。) +2. 之后是一个输出位置,它表示你需要将值输出到哪里,也可以没有返回值,例如上方的示例中 `[ret] "={rax}" (-> usize)` 代表我们使用 `[ret]` 标记了返回值,并且返回值就是 rax 寄存器中的值,其后的 `(-> usize)` 代表我们整个内联汇编表达式需要返回一个值,当然这里如果是一个变量,就会将 rax 寄存器的值通过`[ret]`标记绑定到变量上。(注意,此处的 `=` 代表只能进行写入操作数,属于是一个约束。) 3. 这是输入操作数,它和输出位置类似,但它可以存在多个输入,并且它也支持“占位符”和相关的约束。 4. 这里是改动的寄存器,用于通知编译器,我们在执行此内联汇编会使用(或者称之为破坏更合适)的寄存器,默认包含了输入和输出寄存器。还有一个特殊标记 `memory`,它会通知编译器内联汇编会写入任意为声明的内存位置。 diff --git a/course/advanced/comptime.md b/course/advanced/comptime.md index 2b99322c..d166a8fb 100644 --- a/course/advanced/comptime.md +++ b/course/advanced/comptime.md @@ -115,7 +115,7 @@ outline: deep :::info 🅿️ 提示 -注意:当前的自托管编译期设计存在某些缺陷(使用自己的堆栈进行comptime函数调用),当宿主机器并没有提供足够大的堆栈时,将导致堆栈溢出,具体问题可以见这个 [issue](https://github.com/ziglang/zig/issues/13724)。 +注意:当前的自托管编译期设计存在某些缺陷(使用自己的堆栈进行 comptime 函数调用),当宿主机器并没有提供足够大的堆栈时,将导致堆栈溢出,具体问题可以见这个 [issue](https://github.com/ziglang/zig/issues/13724)。 ::: diff --git a/course/advanced/interact-with-c.md b/course/advanced/interact-with-c.md index 74a2d18d..9dd46aad 100644 --- a/course/advanced/interact-with-c.md +++ b/course/advanced/interact-with-c.md @@ -65,11 +65,11 @@ C 语言共享类型通常是通过引入头文件实现,这点在 zig 中可 > [!IMPORTANT] > 该部分示例代码暂无 CI 测试,可能存在过期情况,请注意! -既然可以引入头文件,那么毫无疑问同样可以引入由第三方写好的二进制lib库。 +既然可以引入头文件,那么毫无疑问同样可以引入由第三方写好的二进制 lib 库。 以微软开发的跨平台开源 c/c++ 包管理器 _vcpkg_ 的库导入为例,具体安装以及设置环境变量的教程不在这里赘叙,只讲怎么 zig 使用已经编译好的 lib。 -假如你所处的开发环境系统为 "Windows"、处理器架构为 "x64"、vcpkg 安装目录为 "D:\vcpkg"、并且操作模式为 classic(Classic Mode)、要使用并且已安装的库为c运算库 `gsl`。 +假如你所处的开发环境系统为 "Windows"、处理器架构为 "x64"、vcpkg 安装目录为 "D:\vcpkg"、并且操作模式为 classic(Classic Mode)、要使用并且已安装的库为 c 运算库 `gsl`。 那么在 `build.zig` 文件中, @@ -79,13 +79,13 @@ C 语言共享类型通常是通过引入头文件实现,这点在 zig 中可 <<<@/code/release/import_vcpkg/src/main.zig#import_gsl -然后使用 `gsl_fft_complex_radix2_forward` 函数计算从1到n的复数数组的离散傅里叶变换 +然后使用 `gsl_fft_complex_radix2_forward` 函数计算从 1 到 n 的复数数组的离散傅里叶变换 <<<@/code/release/import_vcpkg/src/main.zig#use_gsl_fft ::: info 🅿️ 提示 -zig 使用 c++ 库的方式同c一样,需要保证该库 `extern "C"`,并且在需要使用动态库的时候也同样不能少。 +zig 使用 c++ 库的方式同 c 一样,需要保证该库 `extern "C"`,并且在需要使用动态库的时候也同样不能少。 ::: @@ -215,7 +215,7 @@ zig 支持外部(`extern`)可变参数函数: 实际上,zig 本身实现了一个 C 的编译器(目前仅限 linux,其他平台仍使用 llvm),当然不仅仅如此,zig 还提供了一个比较 **_magic_** 的东西—— [`glibc-abi-tool`](https://github.com/ziglang/glibc-abi-tool),这是一个收集每个版本的 glibc 的 `.abilist` 文件的存储库,还包含一个将它们组合成一个数据集的工具。 -所以,zig 本身所谓的 “**_ships with libc_**” 并不准确,它的确分发 libc,但它只携带每个版本的符号库,仅依赖这个符号库,zig 就可以实现在没有 libc 的情况下仍然正确地进行动态链接! +所以,zig 本身所谓的“**_ships with libc_**”并不准确,它的确分发 libc,但它只携带每个版本的符号库,仅依赖这个符号库,zig 就可以实现在没有 libc 的情况下仍然正确地进行动态链接! ::: info 🅿️ 提示 @@ -241,7 +241,7 @@ zig 支持静态链接 musl(针对 linux 的另一个 libc,目标为嵌入 CC='zig cc -target x86_64-linux-gnu' CXX='zig cc -target x86_64-linux-gnu' go build ``` -设置 zig 作为 C 编译器来供 go 使用,只要对 zig 和 go 设置正确的target,就可以在本机实现完善的交叉编译。 +设置 zig 作为 C 编译器来供 go 使用,只要对 zig 和 go 设置正确的 target,就可以在本机实现完善的交叉编译。 再进一步,我们还可以构建出 linux 的使用 cgo 的静态链接的二进制可执行文件: diff --git a/course/advanced/memory_manage.md b/course/advanced/memory_manage.md index de999f51..6f3a82d0 100644 --- a/course/advanced/memory_manage.md +++ b/course/advanced/memory_manage.md @@ -6,7 +6,7 @@ outline: deep > zig 在内存管理方面采取了类似 C 的方案,完全由程序员管理内存,这也是为什么 zig 没有运行时开销的原因,同时这也是为什么 zig 可以在如此多环境(包括实时软件、操作系统内核、嵌入式设备和低延迟服务器)中无缝工作的原因。 -事实上,在 C 开发中最难以调试的 bug 往往是由于错误的内存管理引起的, zig 在此基础上给我们提供了少量的保护,但仅仅是少量的保护,这就要求程序员在需要明白数据在内存中真实存在的模样(这就涉及到计算机组成原理和操作系统的理论知识了,当然还涉及到一点点的汇编知识)。 +事实上,在 C 开发中最难以调试的 bug 往往是由于错误的内存管理引起的,zig 在此基础上给我们提供了少量的保护,但仅仅是少量的保护,这就要求程序员在需要明白数据在内存中真实存在的模样(这就涉及到计算机组成原理和操作系统的理论知识了,当然还涉及到一点点的汇编知识)。 事实上,zig 本身的标准库为我们提供了多种内存分配模型: @@ -63,7 +63,7 @@ outline: deep ## `ArenaAllocator` -这个分配器的特点是你可以多次申请内存,并无需每次用完时进行 `free` 操作,可以使用 `deinit` 直接一次回收所有分发出去的内存,如果你的程序是一个命令行程序或者没有什么特别的循环模式,例如web server 或者游戏事件循环之类的,那么推荐你使用这个。 +这个分配器的特点是你可以多次申请内存,并无需每次用完时进行 `free` 操作,可以使用 `deinit` 直接一次回收所有分发出去的内存,如果你的程序是一个命令行程序或者没有什么特别的循环模式,例如 web server 或者游戏事件循环之类的,那么推荐你使用这个。 <<<@/code/release/memory_manager.zig#ArenaAllocator @@ -95,7 +95,7 @@ outline: deep 这是最基本的分配器,它仅仅是实现了不同系统的分页申请系统调用。 -每次执行分配时,它都会向操作系统申请整个内存页面。单个字节的分配可能会剩下数千的字节无法使用(现代操作系统页大小最小为4K,但有些系统还支持2M和1G的页),由于涉及到系统调用,它的速度很慢,但好处是线程安全并且无锁。 +每次执行分配时,它都会向操作系统申请整个内存页面。单个字节的分配可能会剩下数千的字节无法使用(现代操作系统页大小最小为 4K,但有些系统还支持 2M 和 1G 的页),由于涉及到系统调用,它的速度很慢,但好处是线程安全并且无锁。 <<<@/code/release/memory_manager.zig#page_allocator @@ -116,7 +116,7 @@ outline: deep > > 此外,由于内存块在物理上是相邻的,因此内存池还可以减少内存碎片。 > -> 内存池也有其缺点,例如,如果内存池的大小设置得不合适(太大或太小),则可能会浪费内存或导致内存不足。 +> 内存池也有其缺点,例如,如果内存池的大小设置得不合适(太大或太小),则可能会浪费内存或导致内存不足。 <<<@/code/release/memory_manager.zig#MemoryPool diff --git a/course/advanced/package_management.md b/course/advanced/package_management.md index 91b2eeb8..fac1ff9b 100644 --- a/course/advanced/package_management.md +++ b/course/advanced/package_management.md @@ -40,7 +40,7 @@ zig 当前并没有一个中心化存储库,包可以来自任何来源,无 例如 `https://github.com/limine-bootloader/limine-zig/archive/trunk.tar.gz` 就是获取 [limine-zig](https://github.com/limine-bootloader/limine-zig) 这个包的主分支源码打包。 -而若是想要离线使用本地包时则是先下载源码包并直接使用绝对或相对路径导入,例如在下载完包之后放在项目的deps目录下,那么使用本地包的格式为: +而若是想要离线使用本地包时则是先下载源码包并直接使用绝对或相对路径导入,例如在下载完包之后放在项目的 deps 目录下,那么使用本地包的格式为: `./deps/tunk.tar.gz` @@ -62,7 +62,7 @@ zig 支持在一个 `build.zig` 中对外暴露出多个模块,也就是说一 如何将模块对外暴露呢? -可以使用 `build` 函数传入的参数 `b: *std.Build`,它包含一个方法 [`addModule`](https://ziglang.org/documentation/master/std/#std.Build.addModule), 它的原型如下: +可以使用 `build` 函数传入的参数 `b: *std.Build`,它包含一个方法 [`addModule`](https://ziglang.org/documentation/master/std/#std.Build.addModule),它的原型如下: ```zig pub fn addModule( @@ -82,13 +82,13 @@ pub fn addModule( 如果需要使用私有的模块,请使用 [`std.Build.createModule`](https://ziglang.org/documentation/master/std/#std.Build.createModule),使用方式和 `addModule` 同理。 -关于二进制构建结果(例如动态链接库和静态链接库),任何被执行 `install` 操作的构建结果均会被暴露出去(即引入该包的项目均可看到该包的构建结果,但需要手动 link )。 +关于二进制构建结果(例如动态链接库和静态链接库),任何被执行 `install` 操作的构建结果均会被暴露出去(即引入该包的项目均可看到该包的构建结果,但需要手动 link)。 ::: ## 引入包 -可以使用 `build` 函数传入的参数 `b: *std.Build`,它包含一个方法 [`dependency`](https://ziglang.org/documentation/master/std/#std.Build.dependency), 它的原型如下: +可以使用 `build` 函数传入的参数 `b: *std.Build`,它包含一个方法 [`dependency`](https://ziglang.org/documentation/master/std/#std.Build.dependency),它的原型如下: ```zig fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency diff --git a/course/advanced/type_cast.md b/course/advanced/type_cast.md index e50fdf98..243ee4c1 100644 --- a/course/advanced/type_cast.md +++ b/course/advanced/type_cast.md @@ -12,7 +12,7 @@ zig 提供了三种类型转换,第一种是已知完全安全且不存在歧 出现时机:当需要一种类型时却提供了另一种类型,如果此时这种转换是安全,且不存在歧义,则会由 zig 自动完成。 -仅当完全明确如何从一种类型转换为另一种类型并且保证转换安全时才允许自动转换,但有一个例外,那就是 zig 的 [C指针](https://ziglang.org/documentation/master/#C-Pointers)。 +仅当完全明确如何从一种类型转换为另一种类型并且保证转换安全时才允许自动转换,但有一个例外,那就是 zig 的 [C 指针](https://ziglang.org/documentation/master/#C-Pointers)。 大致的规则如下: @@ -50,7 +50,7 @@ docgen_tmp/test_ambiguous_coercion.zig:3:25: error: ambiguous coercion of divisi 1. 参照 `5` 的类型,将 `54.0` 转换为 `comptime_int` 就是 `54`,再相除,得到结果再转换为 `f32`,最终 `f` 为 `10`。 -2. 参照 `54.0` 的类型,将 `5` 转换为 `comptime_float` 就是 `5.0`, 再相除,得到结果再转换为 `f32`,最终 `f` 为 `10.8`。 +2. 参照 `54.0` 的类型,将 `5` 转换为 `comptime_float` 就是 `5.0`,再相除,得到结果再转换为 `f32`,最终 `f` 为 `10.8`。 ### 切片、数组、指针 @@ -58,7 +58,7 @@ docgen_tmp/test_ambiguous_coercion.zig:3:25: error: ambiguous coercion of divisi <<<@/code/release/type-cast.zig#pointer_arr_slice_1 -2. 允许直接将数组的指针赋值给切片(会被自动转换),这会使切片长度直接等于数组。 +2. 允许直接将数组的指针赋值给切片 (会被自动转换),这会使切片长度直接等于数组。 <<<@/code/release/type-cast.zig#pointer_arr_slice_2 diff --git a/course/appendix/well-known-lib.md b/course/appendix/well-known-lib.md index 9af922e2..609164f4 100644 --- a/course/appendix/well-known-lib.md +++ b/course/appendix/well-known-lib.md @@ -7,12 +7,12 @@ showVersion: false 这里列出一些仍在积极维护的 Zig 第三方库,你可以进行参考和学习 -- **[zap](https://github.com/zigzap/zap)**: 速度极快的 zig 后端开发库 +- **[zap](https://github.com/zigzap/zap)**:速度极快的 zig 后端开发库 - **[bun](https://github.com/oven-sh/bun)**: 使用 zig 编写的 js 运行时,原生支持 ts 和包管理 - **[mach](https://machengine.org/)**:zig 的游戏引擎和图形套件 -- **[capy](https://github.com/capy-ui/capy)**: 依托于 GTK4 的强大的 GUI 库 +- **[capy](https://github.com/capy-ui/capy)**:依托于 GTK4 的强大的 GUI 库 - **[zld](https://github.com/kubkon/zld)**: zig 实现的 LD 的替代品 -- **[zls](https://github.com/zigtools/zls)**: zig的 language server 实现 +- **[zls](https://github.com/zigtools/zls)**: zig 的 language server 实现 - **[dt](https://github.com/so-dang-cool/dt)**: 用于 unix 的 pipe - **[arocc](https://github.com/Vexu/arocc)**: 使用 zig 编写的 C 编译器 - **[bog](https://github.com/Vexu/bog)**: 一个轻量强类型嵌入式语言 @@ -22,7 +22,7 @@ showVersion: false - **[koino](https://github.com/kivikakk/koino)**: Comrak 的解析器,并且保证与 github 的 markdown 规范兼容 - **[LoLa](https://github.com/MasterQ32/LoLa)**: 适用于游戏的小型脚本语言 - **[tigerbeetle](https://github.com/tigerbeetle/tigerbeetle)**: 专为关键任务安全性和性能而设计的分布式财务会计数据库 -- **[zig-sqlite](https://github.com/vrischmann/zig-sqlite)**: 对 sqlite 的 C API包装库 +- **[zig-sqlite](https://github.com/vrischmann/zig-sqlite)**: 对 sqlite 的 C API 包装库 - **[duckdb](https://github.com/beachglasslabs/duckdb.zig)**: 对 duckdb 的 API 包裹 - **[legend-of-swarkland](https://github.com/thejoshwolfe/legend-of-swarkland)**: 游戏,斯沃克兰的传说 - **[pacman](https://github.com/floooh/pacman.zig)**: 吃豆人游戏的 zig 版本 @@ -31,4 +31,4 @@ showVersion: false - **[minisign](https://github.com/jedisct1/zig-minisign)**: zig 实现的 minisign - **[zig-gamedev](https://github.com/michal-z/zig-gamedev)**: zig 的游戏生态库 - **[zig-webui](https://github.com/webui-dev/zig-webui)**:webui 的包裹,允许 zig 将浏览器作为渲染前端 -- **[zigar](https://github.com/chung-leong/zigar)**: 在JavaScript项目中使用Zig代码 +- **[zigar](https://github.com/chung-leong/zigar)**: 在 JavaScript 项目中使用 Zig 代码 diff --git a/course/basic/advanced_type/enum.md b/course/basic/advanced_type/enum.md index 3005c365..95f04539 100644 --- a/course/basic/advanced_type/enum.md +++ b/course/basic/advanced_type/enum.md @@ -30,7 +30,7 @@ outline: deep ## 枚举方法 -没错,枚举也可以拥有方法,实际上枚举仅仅是一种命名空间(你可以看作是一类 struct )。 +没错,枚举也可以拥有方法,实际上枚举仅仅是一种命名空间(你可以看作是一类 struct)。 <<<@/code/release/enum.zig#enum_with_method diff --git a/course/basic/advanced_type/pointer.md b/course/basic/advanced_type/pointer.md index dd1f2ece..32e0846e 100644 --- a/course/basic/advanced_type/pointer.md +++ b/course/basic/advanced_type/pointer.md @@ -52,7 +52,7 @@ zig 本身支持指针运算(加减操作),但有一点需要注意:最 数组和切片都与指针有紧密的联系。 -`*[N]T`:这是指向一个数组的单项指针,数组的长度为N。也可以将其理解为指向N个元素的指针。 +`*[N]T`:这是指向一个数组的单项指针,数组的长度为 N。也可以将其理解为指向 N 个元素的指针。 `[]T`:这是切片,相当于一个胖指针,包含了一个类型为 `[*]T` 的指针和一个长度。 @@ -76,7 +76,7 @@ zig 本身支持指针运算(加减操作),但有一点需要注意:最 <<<@/code/release/pointer.zig#st_pointer -以上代码编译需要额外连接 libc ,你只需要在你的 `build.zig` 中添加 `exe.linkLibC();` 即可。 +以上代码编译需要额外连接 libc,你只需要在你的 `build.zig` 中添加 `exe.linkLibC();` 即可。 ::: @@ -114,11 +114,11 @@ zig 本身支持指针运算(加减操作),但有一点需要注意:最 ### `volatile` -> 如果不知道什么是指针操作的“ _副作用_ ”,那么这里你可以略过,等你需要时再来查看! +> 如果不知道什么是指针操作的“_副作用_”,那么这里你可以略过,等你需要时再来查看! 对指针的操作应假定为没有副作用。如果存在副作用,例如使用内存映射输入输出(Memory Mapped Input/Output),则需要使用 `volatile` 关键字来修饰。 -在以下代码中,保证使用 `mmio_ptr` 的值进行操作(这里你看起来可能会感到迷惑,在编译代码时,编译器可以能会让值在实际运行过程中进行缓存,这里保证每次都使用 `mmio_ptr` 的值,以避免无法正确触发 “副作用”),并保证了代码执行的顺序。 +在以下代码中,保证使用 `mmio_ptr` 的值进行操作(这里你看起来可能会感到迷惑,在编译代码时,编译器可以能会让值在实际运行过程中进行缓存,这里保证每次都使用 `mmio_ptr` 的值,以避免无法正确触发“副作用”),并保证了代码执行的顺序。 <<<@/code/release/pointer.zig#volatile diff --git a/course/basic/advanced_type/slice.md b/course/basic/advanced_type/slice.md index d31a56a8..651e951c 100644 --- a/course/basic/advanced_type/slice.md +++ b/course/basic/advanced_type/slice.md @@ -30,7 +30,7 @@ slice_2 类型为[]i32 切片的使用方式就是类似数组,不过`[]`中的是索引的边界值,遵循“左闭右开”规则。 -以上我们对数组取切片,左边界值为0,右边界值为 `len` 变量。 +以上我们对数组取切片,左边界值为 0,右边界值为 `len` 变量。 注意,这里说的是边界值有一个是变量(运行时可知),如果两个边界值均是编译期可知的话,编译器会直接将切片优化为数组指针。 diff --git a/course/basic/advanced_type/string.md b/course/basic/advanced_type/string.md index 70e421c0..0f7d7ced 100644 --- a/course/basic/advanced_type/string.md +++ b/course/basic/advanced_type/string.md @@ -30,7 +30,7 @@ Unicode 码点字面量类型是 `comptime_int`,所有的转义字符均可以 > 对包含非 ASCII 字节的字符串进行索引会返回单个字节,无论是否为有效的 UTF-8。 -为了方便处理 UTF-8 和 Unicode ,zig的标准库 `std.unicode` 中实现了相关的函数来处理它们。 +为了方便处理 UTF-8 和 Unicode,zig 的标准库 `std.unicode` 中实现了相关的函数来处理它们。 关于字符串有一个示例: diff --git a/course/basic/advanced_type/struct.md b/course/basic/advanced_type/struct.md index ea80a0f6..8291e0c2 100644 --- a/course/basic/advanced_type/struct.md +++ b/course/basic/advanced_type/struct.md @@ -125,7 +125,7 @@ zig 在使用结构体的时候还支持省略结构体类型,只要能让 zig :::info 🅿️ 提示 -使用 Go 的朋友对这个可能很熟悉,在 Go 中经常用空结构体做实体在 chan 中传递,它的内存大小为 0 ! +使用 Go 的朋友对这个可能很熟悉,在 Go 中经常用空结构体做实体在 chan 中传递,它的内存大小为 0! ::: @@ -145,7 +145,7 @@ zig 在使用结构体的时候还支持省略结构体类型,只要能让 zig <<<@/code/release/struct.zig#tuple -当然,以上的语法很啰嗦,所以 zig 提供了类似**数组的语法**来访问元组,例如 `values[3]` 的值就是 "hi"。 +当然,以上的语法很啰嗦,所以 zig 提供了类似**数组的语法**来访问元组,例如 `values[3]` 的值就是 "hi"。 :::info 🅿️ 提示 @@ -171,7 +171,7 @@ zig 在使用结构体的时候还支持省略结构体类型,只要能让 zig - 字段严格按照声明的顺序排列 - 在不同字段之间不会存在位填充(不会发生内存对齐) -- zig 支持任意位宽的整数(通常不足8位的仍然使用8位),但在 `packed` 下,会只使用它们的位宽 +- zig 支持任意位宽的整数(通常不足 8 位的仍然使用 8 位),但在 `packed` 下,会只使用它们的位宽 - `bool` 类型的字段,仅有一位 - 枚举类型只使用其整数标志位的位宽 - 联合类型只使用其最大位宽 diff --git a/course/basic/advanced_type/vector.md b/course/basic/advanced_type/vector.md index d90156e0..c3fe424f 100644 --- a/course/basic/advanced_type/vector.md +++ b/course/basic/advanced_type/vector.md @@ -54,7 +54,7 @@ Zig 支持任何已知的最大 2^32-1 向量长度。请注意,过长的向 注意:`.Add` 和 `.Mul` 在整型上的操作是 **wrapping**。 - + ::: @@ -69,7 +69,7 @@ Zig 支持任何已知的最大 2^32-1 向量长度。请注意,过长的向 ) @Vector(mask_len, E) ``` -根据掩码`mask`(一个向量 Vector),返回向量 a 或者向量 b 的值,组成一个新的向量,mask 的长度决定返回的向量的长度,并且逐个根据 mask 中的值,来从 a 或 b选出值,正数是从 a 选出指定索引的值(从 0 开始,变大),负数是从 b 选出指定索引的值(从 -1 开始,变小)。 +根据掩码`mask`(一个向量 Vector),返回向量 a 或者向量 b 的值,组成一个新的向量,mask 的长度决定返回的向量的长度,并且逐个根据 mask 中的值,来从 a 或 b 选出值,正数是从 a 选出指定索引的值(从 0 开始,变大),负数是从 b 选出指定索引的值(从 -1 开始,变小)。 ::: info 🅿️ 提示 diff --git a/course/basic/basic_type/char-and-boolean.md b/course/basic/basic_type/char-and-boolean.md index 75956ce7..22af7efc 100644 --- a/course/basic/basic_type/char-and-boolean.md +++ b/course/basic/basic_type/char-and-boolean.md @@ -64,4 +64,4 @@ zig 还提供了 `c_char` 类型,对应 C 中的 `char` 类型。主要用于 > 常用于流程控制 -在 zig 中,布尔值有两个,分别是 `true` 和 `false`, 它们在内存中占用的大小为1个字节。 +在 zig 中,布尔值有两个,分别是 `true` 和 `false`,它们在内存中占用的大小为 1 个字节。 diff --git a/course/basic/basic_type/function.md b/course/basic/basic_type/function.md index 91951abb..04548e18 100644 --- a/course/basic/basic_type/function.md +++ b/course/basic/basic_type/function.md @@ -16,7 +16,7 @@ zig 的函数明显,你可以一眼就看出来它的组成,我们来用一 下面来进行说明: -1. `pub` 是访问修饰符,有且只有一个选择,那就是 `pub`,这代表着函数是公共可访问的(其他的文件import该文件后,可以直接使用这个函数)。 +1. `pub` 是访问修饰符,有且只有一个选择,那就是 `pub`,这代表着函数是公共可访问的(其他的文件 import 该文件后,可以直接使用这个函数)。 2. `fn` 是关键字,代表着我们接下来定义了一个函数。 3. `add` 是标识符,作为函数的名字。 4. `a: u8` 是参数的标识符和类型,这里有两个参数,分别是 `a` 和 `b`,它们的类型均是 `u8`。 @@ -62,7 +62,7 @@ zig 在这方面的处理则是,原始类型(整型、布尔这种)传递 :::info 🅿️ 提示 -对于外部函数(使用 `extern` 修饰),Zig 遵循 C ABI 按值传递结构和联合类型。 +对于外部函数 (使用 `extern` 修饰),Zig 遵循 C ABI 按值传递结构和联合类型。 ::: @@ -88,7 +88,7 @@ zig 在这方面的处理则是,原始类型(整型、布尔这种)传递 > > 环境里是若干对符号和值的对应关系,它既要包括约束变量(该函数内部绑定的符号),也要包括自由变量(在函数外部定义但在函数内被引用),有些函数也可能没有自由变量。闭包跟函数最大的不同在于,当捕捉闭包的时候,它的自由变量会在捕捉时被确定,这样即便脱离了捕捉时的上下文,它也能照常运行。 > -> 捕捉时对于值的处理可以是值拷贝,也可以是名称引用,这通常由语言设计者决定,也可能由用户自行指定(如C++)。 +> 捕捉时对于值的处理可以是值拷贝,也可以是名称引用,这通常由语言设计者决定,也可能由用户自行指定(如 C++)。 在 zig 中,由于语言本身的限制(这是出于某种角度考虑而做出的限制),我们无法自由地使用闭包特性。 @@ -109,10 +109,10 @@ def outer_function(): closure = outer_function() # 调用闭包 -closure() # 输出: Hello, World! +closure() # 输出:Hello, World! ``` -以上是一段 `python` 代码,其中 `outer_function` 函数最后返回一个函数类型(实际上它返回了函数 `inner_function`,但这不严谨,因为在解释运行的时候它不会叫做 `inner_function`)。 +以上是一段 `python` 代码,其中 `outer_function` 函数最后返回一个函数类型 (实际上它返回了函数 `inner_function`,但这不严谨,因为在解释运行的时候它不会叫做 `inner_function`)。 Zig 语言不允许在函数内声明函数,也不允许直接创建匿名函数。这两个功能构成了在其他编程语言(例如 JavaScript、PowerQuery-M 等)中实现闭包模式的通用模式。 @@ -122,7 +122,7 @@ Zig 语言不允许在函数内声明函数,也不允许直接创建匿名函 函数 `bar` 返回一个函数类型`fn (i32) i32`,接收一个编译期的参数,这使得该函数可以访问编译期传入的数据。 -与此同时我们使用了匿名函数(匿名结构体方法): +与此同时我们使用了匿名函数 (匿名结构体方法): <<<@/code/release/function.zig#lambda diff --git a/course/basic/basic_type/number.md b/course/basic/basic_type/number.md index 47d4bcdd..a4587fd6 100644 --- a/course/basic/basic_type/number.md +++ b/course/basic/basic_type/number.md @@ -4,7 +4,7 @@ outline: deep # 数值类型 -> 数值类型是语言运行时的基本类型,当它编译为机器码时,其中包含着许多的 _CPU运算器_ 的操作指令。 +> 数值类型是语言运行时的基本类型,当它编译为机器码时,其中包含着许多的 _CPU 运算器_ 的操作指令。 ## 整数 @@ -12,25 +12,25 @@ outline: deep 在 zig 中,对整数的类型划分很详细,以下是类型表格: -| 类型 | 对应C类型 | 描述 | +| 类型 | 对应 C 类型 | 描述 | | -------------- | -------------------- | ------------------------------ | -| `i8` | `int8_t` | 有符号8位整数 | -| `u8` | `uint8_t` | 无符号8位整数 | -| `i16` | `int16_t` | 有符号16位整数 | -| `u16` | `uint16_t` | 无符号16位整数 | -| `i32` | `int32_t` | 有符号32位整数 | -| `u32` | `uint32_t` | 无符号32位整数 | -| `i64` | `int64_t` | 有符号64位整数 | -| `u64` | `uint64_t` | 无符号64位整数 | -| `i128` | `__int128` | 有符号128位整数 | -| `u128` | `unsigned __int128` | 无符号128位整数 | +| `i8` | `int8_t` | 有符号 8 位整数 | +| `u8` | `uint8_t` | 无符号 8 位整数 | +| `i16` | `int16_t` | 有符号 16 位整数 | +| `u16` | `uint16_t` | 无符号 16 位整数 | +| `i32` | `int32_t` | 有符号 32 位整数 | +| `u32` | `uint32_t` | 无符号 32 位整数 | +| `i64` | `int64_t` | 有符号 64 位整数 | +| `u64` | `uint64_t` | 无符号 64 位整数 | +| `i128` | `__int128` | 有符号 128 位整数 | +| `u128` | `unsigned __int128` | 无符号 128 位整数 | | `isize` | `intptr_t` | 有符号指针大小的整数 | | `usize` | `uintptr_t` `size_t` | 无符号指针大小的整数 | | `comptime_int` | 无 | 编译期的整数,整数字面量的类型 | <<<@/code/release/number.zig#type -同时 zig 支持任意位宽的整数,使用 `u` 或者 `i` 后面加数字即可,例如 `i7` 代表有符号的7位整数,整数类型允许的最大位宽为`65535`。 +同时 zig 支持任意位宽的整数,使用 `u` 或者 `i` 后面加数字即可,例如 `i7` 代表有符号的 7 位整数,整数类型允许的最大位宽为`65535`。 ::: tip 🅿️ 提示 `usize` 和 `isize` 这两种类型的的大小取决于,运行程序的目标计算机 CPU 的类型:32 位 CPU 则两个类型均为 32 位,64 位同理。 @@ -129,7 +129,7 @@ zig 中,有以下默认操作可以导致溢出: - [`@mulWithOverflow`](https://ziglang.org/documentation/master/#mulWithOverflow) - [`@shlWithOverflow`](https://ziglang.org/documentation/master/#shlWithOverflow) -这些内建函数返回一个元组,其中包含是否存在溢出(作为 `u1`)以及操作中可能溢出的位. +这些内建函数返回一个元组,其中包含是否存在溢出(作为 `u1`)以及操作中可能溢出的位。 环绕操作符: @@ -142,11 +142,11 @@ zig 中,有以下默认操作可以导致溢出: ## 浮点数 -浮点数就是表示带有小数点的数字。在 zig 中,浮点数有 `f16`、`f32`、`f64`、`f80`、`f128`、`c_longdouble`(对应C ABI的 `long double` )。 +浮点数就是表示带有小数点的数字。在 zig 中,浮点数有 `f16`、`f32`、`f64`、`f80`、`f128`、`c_longdouble`(对应 C ABI 的 `long double` )。 值得注意的是,`comptime_float` 具有 `f128` 的精度和运算。 -浮点字面量可以隐式转换为 _任意浮点类型_,如果没有小数部分的话还能够隐式转换为 _任意整数类型_ 。 +浮点字面量可以隐式转换为 _任意浮点类型_,如果没有小数部分的话还能够隐式转换为 _任意整数类型_。 浮点运算时遵循 `Strict` 模式,但是可以使用 `@setFloatMode(.Optimized)` 切换到 `Optimized` 模式,有关浮点运算的模式,详见 [`@setFloatMode`](https://ziglang.org/documentation/master/#setFloatMode)。 @@ -168,7 +168,7 @@ zig 并未像其他语言那样默认提供了 NaN、无穷大、负无穷大这 const std = @import("std"); pub fn main() void { - // assert用于断言,常用于单元测试和调试 + // assert 用于断言,常用于单元测试和调试 std.debug.assert(0.1 + 0.2 == 0.3); } ``` @@ -179,13 +179,13 @@ pub fn main() void { ## 运算 -常规的运算有等于(`==`),不等于(`!=`),大于(`>`),小于(`<`),大于等于(`>=`),小于等于(`<=`),加减乘除(`+`, `-`, `*`, `/`),左移右移(`<<`,`>>`),与或非(`and`, `or`, `!`),按位与(`&`),按位或(`|`),按位异或(`^`),按位非(`~`), +常规的运算有等于 (`==`),不等于 (`!=`),大于 (`>`),小于 (`<`),大于等于 (`>=`),小于等于 (`<=`),加减乘除(`+`, `-`, `*`, `/`),左移右移 (`<<`,`>>`),与或非 (`and`, `or`, `!`),按位与 (`&`),按位或 (`|`),按位异或 (`^`),按位非 (`~`), > 常见的加减乘除我们就不聊了,聊点 zig 中独具特色的小玩意。 -- `+|`:饱和加法,这涉及到[对等类型解析](../../advanced/type_cast.md#对等类型转换),你现在只需要知道加法结果最多只是该类型的极限即可,例如 `u8` 类型的 255 + 1 后还是 255 。 +- `+|`:饱和加法,这涉及到[对等类型解析](../../advanced/type_cast.md#对等类型转换),你现在只需要知道加法结果最多只是该类型的极限即可,例如 `u8` 类型的 255 + 1 后还是 255。 - `-|`:饱和减法,和上面一样,减法结果最小为该类型的极限。 - `*|`:饱和乘法,同上,乘法结果最大或最小为该类型的极限。 - `<<|`:饱和左移,同之前,结果为该类型的极限。 diff --git a/course/basic/error_handle.md b/course/basic/error_handle.md index 6a2dbd9a..e24680a7 100644 --- a/course/basic/error_handle.md +++ b/course/basic/error_handle.md @@ -87,7 +87,7 @@ outline: deep :::info 🅿️ 提示 -`catch` 运算符右侧必须是一个与其左侧函数返回的错误联合类型展开后的类型(也就是除了错误类型外的类型)一致,或者是一个 `noreturn`(例如 `panic`) 的语句。 +`catch` 运算符右侧必须是一个与其左侧函数返回的错误联合类型展开后的类型 (也就是除了错误类型外的类型) 一致,或者是一个 `noreturn`(例如 `panic`) 的语句。 ::: @@ -176,7 +176,7 @@ outline: deep 上面这句话看起来有点云里雾里,我们来两个例子来说明就可以: -1. 不同构建目标之间可能存在着专属于架构的错误定义,这使得在不同架构上构建出来的代码的实际错误集并不相同,函数也同理(与cpu指令集实现有关)。 +1. 不同构建目标之间可能存在着专属于架构的错误定义,这使得在不同架构上构建出来的代码的实际错误集并不相同,函数也同理(与 cpu 指令集实现有关)。 2. 当我们使用自动推导时,推导出的错误集是最小错误集,故可能一个函数被推导出 `ErrorSetOne!type` 和 `ErrorSetTwo!type` 两个错误集,这就使得在递归上出现了不兼容,不过可以使用 `switch` 来匹配错误集来解决该问题。 对于上面的问题,其实更好的解决办法就是显式声明一个错误集,这会明确告诉编译器返回的错误种类都有什么。 diff --git a/course/basic/optional_type.md b/course/basic/optional_type.md index ed78d595..32caf35d 100644 --- a/course/basic/optional_type.md +++ b/course/basic/optional_type.md @@ -4,7 +4,7 @@ outline: deep # 可选类型 -zig 在不损害效率和可读性的前提下提高代码安全性的一个方案就是可选类型,`?` 是可选类型的标志,你可以将它放在类型的前面,代表它的值是null或者这个类型。 +zig 在不损害效率和可读性的前提下提高代码安全性的一个方案就是可选类型,`?` 是可选类型的标志,你可以将它放在类型的前面,代表它的值是 null 或者这个类型。 <<<@/code/release/optional_type.zig#basic_type @@ -12,7 +12,7 @@ zig 在不损害效率和可读性的前提下提高代码安全性的一个方 当然这在 zig 中不存在,通过可选类型我们可以解决这个问题,zig 在解决空指针上采取的方式比较保守,它兼顾了代码的可读性和效率问题。 -其中目前最为激进的应该是 _Rust_ ,它真的是非常的激进,这增加了程序员在写代码时的心智负担(因为你经常需要和编译期斗智斗勇,但好处大大是减少了你在运行时 _Debug_ 的负担)。相对来说,zig 采取的是一种折中的方案,编译期仍然会给你检测,并且这种检测不是很深奥,而且纠正起来很简单,缺点是并不能保证你的运行时是绝对安全的(可选类型仅仅能保证你不使用空指针,却不能保证你出现悬空指针【迷途指针、野指针】等情况的出现)。 +其中目前最为激进的应该是 _Rust_,它真的是非常的激进,这增加了程序员在写代码时的心智负担(因为你经常需要和编译期斗智斗勇,但好处大大是减少了你在运行时 _Debug_ 的负担)。相对来说,zig 采取的是一种折中的方案,编译期仍然会给你检测,并且这种检测不是很深奥,而且纠正起来很简单,缺点是并不能保证你的运行时是绝对安全的(可选类型仅仅能保证你不使用空指针,却不能保证你出现悬空指针【迷途指针、野指针】等情况的出现)。 zig 会将 `null` 特殊看待,并且保证你不会将一个可能为 `null` 的值赋值给一个不可能是 `null` 的变量。 @@ -23,7 +23,7 @@ zig 会将 `null` 特殊看待,并且保证你不会将一个可能为 `null` <<<@/code/release/optional_type.zig#malloc [zig] ```c [c] -// 引用的是malloc的原型 +// 引用的是 malloc 的原型 void *malloc(size_t size); struct Foo *do_a_thing(void) { @@ -57,7 +57,7 @@ void do_a_thing(struct Foo *foo) { 看起来区别不大,zig 只是在 if 语法有点不同,这个块中保证了 `foo` 不是一个可选类型的指针,而是一个指针。 -当然在 c 中你可以使用 `__attribute__((nonnull))` 来告诉 GCC 编译器这里不能是一个 null ,但使用成本明显要比 zig 高。 +当然在 c 中你可以使用 `__attribute__((nonnull))` 来告诉 GCC 编译器这里不能是一个 null,但使用成本明显要比 zig 高。 ## 编译期反射访问可选类型 diff --git a/course/basic/process_control/loop.md b/course/basic/process_control/loop.md index 5c32e9d8..747e2967 100644 --- a/course/basic/process_control/loop.md +++ b/course/basic/process_control/loop.md @@ -24,7 +24,7 @@ for 循环是另一种循环处理方式,主要用于迭代数组和切片。 <<<@/code/release/loop.zig#for_handle_array -以上代码中的value是一个指针,我们称之为对 数组(切片)迭代的指针捕获,注意它也是只读的,不过我们可以通过借引用指针来操作数组(切片)的值。 +以上代码中的 value 是一个指针,我们称之为对 数组(切片)迭代的指针捕获,注意它也是只读的,不过我们可以通过借引用指针来操作数组(切片)的值。 ### 迭代数字 @@ -84,7 +84,7 @@ for 循环是另一种循环处理方式,主要用于迭代数组和切片。 ## `while` -while 循环用于重复执行表达式,直到某些条件不再成立. +while 循环用于重复执行表达式,直到某些条件不再成立。 基本使用: @@ -112,7 +112,7 @@ while 还支持一个被称为 continue 表达式的方法来便于我们控制 zig 还允许我们将 while 作为表达式来使用,此时需要搭配 `else` 和 `break`。 -这里的 `else` 是当 while 循环结束并且没有经过 `break` 返回值时触发,而 `break` 则类似于return,可以在 while 内部返回值。 +这里的 `else` 是当 while 循环结束并且没有经过 `break` 返回值时触发,而 `break` 则类似于 return,可以在 while 内部返回值。 <<<@/code/release/loop.zig#while_as_expression diff --git a/course/basic/process_control/switch.md b/course/basic/process_control/switch.md index c926b041..63b7acdd 100644 --- a/course/basic/process_control/switch.md +++ b/course/basic/process_control/switch.md @@ -4,7 +4,7 @@ outline: deep # Switch -switch 语句可以进行匹配,并且switch匹配不能出现遗漏匹配的情况。 +switch 语句可以进行匹配,并且 switch 匹配不能出现遗漏匹配的情况。 ## 基本使用 diff --git a/course/basic/process_control/unreachable.md b/course/basic/process_control/unreachable.md index 9ce6d89b..f8b52252 100644 --- a/course/basic/process_control/unreachable.md +++ b/course/basic/process_control/unreachable.md @@ -6,6 +6,6 @@ outline: deep 在 `Debug` 和 `ReleaseSafe` 模式下,`unreachable` 会调用 `panic` ,并显示消息达到 unreachable code。 -在 `ReleaseFast` 和 `ReleaseSmall` 模式下,编译器假设永远不会执行到 `unreachable` 来对代码进行优化 。 +在 `ReleaseFast` 和 `ReleaseSmall` 模式下,编译器假设永远不会执行到 `unreachable` 来对代码进行优化。 <<<@/code/release/unreachable.zig#unreachable diff --git a/course/basic/union.md b/course/basic/union.md index 3ad44c5b..1d843973 100644 --- a/course/basic/union.md +++ b/course/basic/union.md @@ -4,7 +4,7 @@ outline: deep # 联合类型 -联合类型(union),它实际上是用户定义的一种特殊的类型,划分出一块内存空间用来存储多种类型,但同一时间只能存储一个类型。 +联合类型 (union),它实际上是用户定义的一种特殊的类型,划分出一块内存空间用来存储多种类型,但同一时间只能存储一个类型。 ## 基本使用 diff --git a/course/code/12/package_management_exporter/Readme.md b/course/code/12/package_management_exporter/Readme.md index 7b1e2d29..44e8e91d 100644 --- a/course/code/12/package_management_exporter/Readme.md +++ b/course/code/12/package_management_exporter/Readme.md @@ -1 +1 @@ -该目录仅仅是作为演示用的空项目! +该目录仅仅是作为演示用的空项目! diff --git a/course/code/12/package_management_importer/Readme.md b/course/code/12/package_management_importer/Readme.md index 7b1e2d29..44e8e91d 100644 --- a/course/code/12/package_management_importer/Readme.md +++ b/course/code/12/package_management_importer/Readme.md @@ -1 +1 @@ -该目录仅仅是作为演示用的空项目! +该目录仅仅是作为演示用的空项目! diff --git a/course/code/14/package_management_exporter/Readme.md b/course/code/14/package_management_exporter/Readme.md index 7b1e2d29..44e8e91d 100644 --- a/course/code/14/package_management_exporter/Readme.md +++ b/course/code/14/package_management_exporter/Readme.md @@ -1 +1 @@ -该目录仅仅是作为演示用的空项目! +该目录仅仅是作为演示用的空项目! diff --git a/course/code/14/package_management_importer/Readme.md b/course/code/14/package_management_importer/Readme.md index 7b1e2d29..44e8e91d 100644 --- a/course/code/14/package_management_importer/Readme.md +++ b/course/code/14/package_management_importer/Readme.md @@ -1 +1 @@ -该目录仅仅是作为演示用的空项目! +该目录仅仅是作为演示用的空项目! diff --git a/course/engineering/build-system.md b/course/engineering/build-system.md index 0a55401b..87a08486 100644 --- a/course/engineering/build-system.md +++ b/course/engineering/build-system.md @@ -36,7 +36,7 @@ Zig 使用 `build.zig` 文件来描述一个项目的构建步骤。 `Step` 会在下一小节中会重点讲述,这里介绍一下上面这个构建文件的其他部分: - `b.standardTargetOptions`: 允许构建器读取来自命令行参数的**构建目标三元组**。 -- `b.standardOptimizeOption`: 允许构建器读取来自命令行参数的**构建优化模式**。 +- `b.standardOptimizeOption`:允许构建器读取来自命令行参数的**构建优化模式**。 - `b.addExecutable`:创建一个 [`Build.Step.Compile`](https://ziglang.org/documentation/master/std/#std.Build.Step.Compile) 并返回对应的指针,其参数为 [`std.Build.ExecutableOptions`](https://ziglang.org/documentation/master/std/#std.Build.ExecutableOptions)。 - `b.path`:该函数用于指定获取当前项目的源文件路径,请勿手动为 `root_source_file` 赋值! @@ -172,7 +172,7 @@ zig 本身提供了一个实验性的文档生成器,它支持搜索查询, 每个文件可以使用 `zig test` 命令来执行测试,但实际开发中这样很不方便,zig 的构建系统提供了另外一种方式来处理当项目变得复杂时的测试。 -使用构建系统执行单元测试时,构建器和测试器会通过 stdin 和 stdout 进行通信,以便同时运行多个测试,并且可以有效地报告错误(不会将错误混到一起),但这导致了无法 [在单元测试中写入 stdin](https://github.com/ziglang/zig/issues/15091),这会扰乱测试器的正常工作。另外, zig 将引入一个额外的机制,允许 [预测 `panic`](https://github.com/ziglang/zig/issues/1356)。 +使用构建系统执行单元测试时,构建器和测试器会通过 stdin 和 stdout 进行通信,以便同时运行多个测试,并且可以有效地报告错误(不会将错误混到一起),但这导致了无法 [在单元测试中写入 stdin](https://github.com/ziglang/zig/issues/15091),这会扰乱测试器的正常工作。另外,zig 将引入一个额外的机制,允许 [预测 `panic`](https://github.com/ziglang/zig/issues/1356)。 <<<@/code/release/build_system/test/build.zig @@ -188,7 +188,7 @@ zig 本身提供了一个实验性的文档生成器,它支持搜索查询, 最常用的一个 target 设置可能是 `b.standardTargetOptions`,它会允许读取命令行输入来决定构建目标 target,它返回一个 [`ResolvedTarget`](https://ziglang.org/documentation/master/std/#std.Build.ResolvedTarget)。 -如果需要手动指定一个 target,可以手动构建一个 `std.Target.Query` 传递给构建(`addExecutable` 和 `addStaticLibrary` 等),如: +如果需要手动指定一个 target,可以手动构建一个 `std.Target.Query` 传递给构建(`addExecutable` 和 `addStaticLibrary` 等),如: <<<@/code/release/build_system/build.zig#crossTarget @@ -216,7 +216,7 @@ zig 本身提供了一个实验性的文档生成器,它支持搜索查询, ### 执行外部命令 -zig 的构建系统还允许我们执行一些额外的命令,录入根据 json 生成某些特定的文件(例如 zig 源代码),构建其他的编程语言(不只是 C / C++),如Golang、Rust、前端项目构建等等! +zig 的构建系统还允许我们执行一些额外的命令,录入根据 json 生成某些特定的文件(例如 zig 源代码),构建其他的编程语言(不只是 C / C++),如 Golang、Rust、前端项目构建等等! 例如我们可以让 zig 在构建时调用系统的 sh 来输出 hello 并使用 `@embedFile` 传递给包: @@ -230,7 +230,7 @@ zig 的构建系统还允许我们执行一些额外的命令,录入根据 jso ### 构建纯 C++ 项目 -由于 GTK 的 C++ 构建过于复杂(需要手动编译gtkmm),故我们这里选择构建一个 [tinytetris](https://github.com/taylorconor/tinytetris): +由于 GTK 的 C++ 构建过于复杂(需要手动编译 gtkmm),故我们这里选择构建一个 [tinytetris](https://github.com/taylorconor/tinytetris): ::: warning @@ -256,7 +256,7 @@ zig 的构建系统还允许我们执行一些额外的命令,录入根据 jso ::: warning 关于 `libc++` 的问题 -zig 的工具链使用的是 `libc++`(LLVM ABI),而GNU的则是 `libstdc++`,两者的标准库实现略有不同,这会导致混用可能出现问题! +zig 的工具链使用的是 `libc++`(LLVM ABI),而 GNU 的则是 `libstdc++`,两者的标准库实现略有不同,这会导致混用可能出现问题! 正确的做法是,手动编译依赖的源代码(一般是出现问题的),或者使用 `-nostdinc++ -nostdlib++` 指示不使用默认标准库,并链接 GNU 的标准库,具体可以参考该 [issue](https://github.com/ziglang/zig/issues/18300)。 diff --git a/course/environment/editor.md b/course/environment/editor.md index f57d0a1d..1fb0bbe5 100644 --- a/course/environment/editor.md +++ b/course/environment/editor.md @@ -10,9 +10,9 @@ outline: deep 官网地址:[https://code.visualstudio.com/](https://code.visualstudio.com/) -> Visual Studio Code 是一款由微软开发且跨平台的免费源代码编辑器。该软件以扩展的方式支持语法高亮、代码自动补全、代码重构功能,并且内置了命令行工具和Git 版本控制系统。用户可以更改主题和键盘快捷方式实现个性化设置,也可以通过内置的扩展程序商店安装其他扩展以拓展软件功能。 +> Visual Studio Code 是一款由微软开发且跨平台的免费源代码编辑器。该软件以扩展的方式支持语法高亮、代码自动补全、代码重构功能,并且内置了命令行工具和 Git 版本控制系统。用户可以更改主题和键盘快捷方式实现个性化设置,也可以通过内置的扩展程序商店安装其他扩展以拓展软件功能。 -目前最轻量且生态丰富的编辑器,微软出品,zig 官方为其开发了插件,仅需要安装 [`Zig Language`](https://marketplace.visualstudio.com/items?itemName=ziglang.vscode-zig)这个插件即可,在初次初始化时会推荐安装 _language server_, 确认即可! +目前最轻量且生态丰富的编辑器,微软出品,zig 官方为其开发了插件,仅需要安装 [`Zig Language`](https://marketplace.visualstudio.com/items?itemName=ziglang.vscode-zig)这个插件即可,在初次初始化时会推荐安装 _language server_,确认即可! ![vscode-zig](/picture/basic/vscode-zig.png){data-zoomable} @@ -40,7 +40,7 @@ vim.g.zig_fmt_autosave = false ::: -如果使用`coc.nvim`作为 _language server_,则推荐使用 [**coc-zls**](https://github.com/xiyaowong/coc-zls),会自动下载最新的zls并配置好,如果使用 **neovim** 的内置 LSP 功能,则推荐使用 [**mason.nvim**](https://github.com/williamboman/mason.nvim) 和 [**mason-lspconfig.nvim**](https://github.com/williamboman/mason-lspconfig.nvim)。 +如果使用`coc.nvim`作为 _language server_,则推荐使用 [**coc-zls**](https://github.com/xiyaowong/coc-zls),会自动下载最新的 zls 并配置好,如果使用 **neovim** 的内置 LSP 功能,则推荐使用 [**mason.nvim**](https://github.com/williamboman/mason.nvim) 和 [**mason-lspconfig.nvim**](https://github.com/williamboman/mason-lspconfig.nvim)。 ::: tip 🅿️ 提示 mason 所安装的 zls 为稳定版本,如果需要 `nightly` 版本,有两种方案可以选择,安装 Zig.nvim 插件,或者手动编译。 @@ -50,13 +50,13 @@ mason 所安装的 zls 为稳定版本,如果需要 `nightly` 版本,有两 - 手动编译安装的方法如下: ```sh -# 单独创建一个source目录 +# 单独创建一个 source 目录 mkdir source cd source git clone https://github.com/zigtools/zls.git cd zls zig build -Doptimize=ReleaseSafe -# 此处将编译后的zls直接覆盖mason的zls +# 此处将编译后的 zls 直接覆盖 mason 的 zls cp zig-out/bin/zls ~/.local/share/nvim/mason/packages/zls/bin/zls ``` @@ -66,7 +66,7 @@ cp zig-out/bin/zls ~/.local/share/nvim/mason/packages/zls/bin/zls ## Emacs -如果说 Vim 是编辑器之神,那么Emacs就是神的编辑器! +如果说 Vim 是编辑器之神,那么 Emacs 就是神的编辑器! Zig 官方维护了 Emacs 的插件 [zig-mode](https://github.com/ziglang/zig-mode),参照页面配置即可。 @@ -78,7 +78,7 @@ Zig 官方维护了 Emacs 的插件 [zig-mode](https://github.com/ziglang/zig-mo 官网地址:[https://visualstudio.microsoft.com/](https://visualstudio.microsoft.com/) -> Microsoft Visual Studio是微软公司的开发工具包系列产品。VS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境等等。 +> Microsoft Visual Studio 是微软公司的开发工具包系列产品。VS 是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如 UML 工具、代码管控工具、集成开发环境等等。 windows 上最棒的开发 IDE,存在第三方插件:[ZigVS](https://marketplace.visualstudio.com/items?itemName=LuckystarStudio.ZigVS)。 @@ -86,7 +86,7 @@ windows 上最棒的开发 IDE,存在第三方插件:[ZigVS](https://marketp > CLion 是一款专为开发 C 及 C++ 所设计的跨平台 IDE。它是以 IntelliJ 为基础设计的,包含了许多智能功能来提高开发人员的生产力。CLion 帮助开发人员使用智能编辑器来提高代码质量、自动代码重构并且深度整合 CMake 编译系统,从而提高开发人员的工作效率。 -原本 CLion 仅仅是 C/C++ 的开发IDE,但在安装插件后可以作为 zig 的 IDE 使用。 +原本 CLion 仅仅是 C/C++ 的开发 IDE,但在安装插件后可以作为 zig 的 IDE 使用。 目前插件市场活跃的两个 zig 插件(均为第三方作者维护)分别是 [ZigBrains](https://plugins.jetbrains.com/plugin/22456-zigbrains) 和 [Zig Support](https://plugins.jetbrains.com/plugin/18062-zig-support),均支持 zig 的 `latest release` 版本。 diff --git a/course/environment/install-environment.md b/course/environment/install-environment.md index 996e05df..da07dde4 100644 --- a/course/environment/install-environment.md +++ b/course/environment/install-environment.md @@ -13,13 +13,13 @@ outline: deep ::: details windows 输出中文乱码问题 -如果你是中文简体用户,那么建议将 windows 的编码修改为UTF-8编码,由于 zig 的源代码编码格式是 UTF-8,导致在windows下向控制台打印输出中文会发生乱码的现象。 +如果你是中文简体用户,那么建议将 windows 的编码修改为 UTF-8 编码,由于 zig 的源代码编码格式是 UTF-8,导致在 windows 下向控制台打印输出中文会发生乱码的现象。 修改方法为: 1. 打开 windows 设置中的 **时间和语言**,进入 **语言和区域**。 2. 点击下方的管理语言设置,在新打开的窗口中点击 **管理**。 -3. 点击下方的 **更改系统区域设置**,勾选下方的 “使用 unicode UTF-8 提供全球语言支持” +3. 点击下方的 **更改系统区域设置**,勾选下方的“使用 unicode UTF-8 提供全球语言支持” 4. 重启计算机。 ::: @@ -102,7 +102,7 @@ choco install zig ## Mac -Mac安装 zig 就很方便,但是如果要使用 `nightly` ,还是需要自行下载并添加环境变量 +Mac 安装 zig 就很方便,但是如果要使用 `nightly` ,还是需要自行下载并添加环境变量 ::: code-group @@ -118,7 +118,7 @@ port install zig ## Linux -Linux安装的话, 由于发行版的不同,安装的方式五花八门,先列出通过包管理器安装 Zig 的方法,再说明如何手动安装 Zig 并设置环境变量。 +Linux 安装的话,由于发行版的不同,安装的方式五花八门,先列出通过包管理器安装 Zig 的方法,再说明如何手动安装 Zig 并设置环境变量。 ### 包管理器安装 diff --git a/course/environment/zig-command.md b/course/environment/zig-command.md index 60e94097..d79e97bb 100644 --- a/course/environment/zig-command.md +++ b/course/environment/zig-command.md @@ -4,7 +4,7 @@ outline: deep # `zig` 命令 -现在,我们已经安装了 zig ,也安装了对应的编辑器,接下来就了解一下基本的 `zig` 命令。 +现在,我们已经安装了 zig,也安装了对应的编辑器,接下来就了解一下基本的 `zig` 命令。 这单单一个命令可神了,它囊括了项目建立、构建、测试、运行,甚至你可以用它来部署你的项目,也可以用来给 C/C++ 作为编译或者依赖管理工具,非常的全面,这一切都是得益于 zig 本身的编译期。 @@ -38,7 +38,7 @@ outline: deep ## `zig ast-check` -对指定文件进行AST语法检查,支持指定文件和标准输入。 +对指定文件进行 AST 语法检查,支持指定文件和标准输入。 ## `zig fmt` @@ -46,7 +46,7 @@ outline: deep ## `zig test` -对指定的源文件运行test,适用于单元测试。 +对指定的源文件运行 test,适用于单元测试。 ## `zig run` diff --git a/course/examples/echo_tcp_server.md b/course/examples/echo_tcp_server.md index 04b1047b..49cd6bc2 100644 --- a/course/examples/echo_tcp_server.md +++ b/course/examples/echo_tcp_server.md @@ -14,11 +14,11 @@ outline: deep Socket(套接字)是计算机网络中用于实现不同计算机或同一台计算机上的不同进程之间的通信的一种技术。它提供了一种标准的 API,程序员可以使用这个 API 来编写网络应用程序。 -一个Socket由三个部分组成:**协议**、**本地地址**和**远程地址**,协议决定了Socket的类型和通信方式,例如TCP或UDP,本地地址是Socket绑定的网络接口和端口号,远程地址是Socket连接的目标网络接口和端口号。 +一个 Socket 由三个部分组成:**协议**、**本地地址**和**远程地址**,协议决定了 Socket 的类型和通信方式,例如 TCP 或 UDP,本地地址是 Socket 绑定的网络接口和端口号,远程地址是 Socket 连接的目标网络接口和端口号。 除了常见的 **TCP** 和 **UDP** 外,还有一种叫做 **Unix Socket**,用于在同一台机器上的不同进程间进行通信,并不使用网络协议栈,而是直接在内核中传递数据,比 TCP 和 UDP 更加高效。 -### IO多路复用 +### IO 多路复用 **I/O 多路复用**是一种允许一个进程同时监视多个 I/O 通道(例如,_socket_、*文件描述符*等),并知道哪个通道可以进行读写操作的技术。这样,一个进程就可以同时处理多个 I/O 操作,而无需为每个 I/O 操作启动一个新的线程或进程。 @@ -48,7 +48,7 @@ I/O 多路复用的常见实现包括 select、poll 和 epoll 等系统调用。 ::: info 🅿️ 提示 -严格来说,**poll** 已经算是一门“过时”的技术,在 linux 平台它被 **epoll** 取代,BSD 系统(包括 mac )则使用 **kqueue**,而 windows 使用 **IOCP(I/O Completion Ports)** 和 **Overlapped I/O**。 +严格来说,**poll** 已经算是一门“过时”的技术,在 linux 平台它被 **epoll** 取代,BSD 系统(包括 mac)则使用 **kqueue**,而 windows 使用 **IOCP(I/O Completion Ports)** 和 **Overlapped I/O**。 WSAPoll For Windows: [WSAPoll function](https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll) @@ -64,7 +64,7 @@ Poll For Linux: [poll(2) — Linux manual page](https://man7.org/linux/man-pages 为了同时兼容 linux 和 windows,我们需要利用一下 zig 的 `builtin` 包来判断构建目标来决定使用的函数(poll 在 windows 上的实现不完全标准)。 -完整的代码在 [Github](https://github.com/zigcc/zig-course/tree/main/course/code/release/echo_tcp_server.zig),测试用的客户端可以使用 _telent_ (windows、linux、mac 均可用)。 +完整的代码在 [Github](https://github.com/zigcc/zig-course/tree/main/course/code/release/echo_tcp_server.zig),测试用的客户端可以使用 _telent_(windows、linux、mac 均可用)。 _server_ 监听端口的实现: diff --git a/course/hello-world.md b/course/hello-world.md index 99b19199..b3b30d0e 100644 --- a/course/hello-world.md +++ b/course/hello-world.md @@ -17,7 +17,7 @@ _很简单,不是吗?_ ## 简单说明 -以上程序中,我们先通过 `@import` 这个内建函数(在zig中有很多的内置函数,它们都以`@`开头,并且遵循 [小驼峰命名法](#))引入了 zig 的标准库。 +以上程序中,我们先通过 `@import` 这个内建函数(在 zig 中有很多的内置函数,它们都以`@`开头,并且遵循 [小驼峰命名法](#))引入了 zig 的标准库。 ::: info 🅿️ 提示 @@ -57,7 +57,7 @@ zig 会自动为我们根据后面的参量表推导出对应的类型,当 zig ::: -这段代码将会分别输出 `Hello out!` 和 `Hello err!`,这里我需要向你讲述一下 `stdout` 和 `stderr` ,它们均是抽象的io(input and output)流句柄(关于流这个概念可能不好解释,你暂时就当作像水流一样的数据的就行)。`stdout` 用于正常的输出,它可能会出现错误导致写入失败。`stderr` 用于错误输出,我们假定 `stderr` 一定不会失败(这个是操作系统负责保证的),这就是它们的区别。 +这段代码将会分别输出 `Hello out!` 和 `Hello err!`,这里我需要向你讲述一下 `stdout` 和 `stderr` ,它们均是抽象的 io(input and output)流句柄(关于流这个概念可能不好解释,你暂时就当作像水流一样的数据的就行)。`stdout` 用于正常的输出,它可能会出现错误导致写入失败。`stderr` 用于错误输出,我们假定 `stderr` 一定不会失败(这个是操作系统负责保证的),这就是它们的区别。 通过 `io` 模块获取到了标准输出和错误输出的 `writer` 句柄,这个句柄实现流`print`函数,我们只需要正常打印即可! @@ -67,7 +67,7 @@ zig 会自动为我们根据后面的参量表推导出对应的类型,当 zig <<<@/code/release/hello_world.zig#three -此时我们就分别得到了使用缓冲区的 `stdout` 和 `stderr`, 性能更高了! +此时我们就分别得到了使用缓冲区的 `stdout` 和 `stderr`,性能更高了! ## 更进一步? diff --git a/course/index.md b/course/index.md index d4408238..34812941 100644 --- a/course/index.md +++ b/course/index.md @@ -12,7 +12,7 @@ showVersion: false 这样的概念解释可能比较模糊,我们来看看维基百科怎么说的: > Zig 是一种命令式、通用、静态类型、编译的系统编程语言,由 Andrew Kelley 设计。 -> 它旨在替代C编程语言,其目标是更小,编程更简单,同时还提供现代功能,新的优化和各种安全机制, +> 它旨在替代 C 编程语言,其目标是更小,编程更简单,同时还提供现代功能,新的优化和各种安全机制, > 同时不像其他语言那样对运行时安全性的要求。 > 语言简单性的改进与流控制、函数调用、库导入、变量声明和 Unicode 支持有关。 @@ -35,7 +35,7 @@ showVersion: false - 手动内存控制,精确的内存泄漏跟踪 - 完善的堆栈跟踪(在裸机器上也可以) - 对交叉编译的一流支持 -- 标准库集成 libc ,但不依赖它 +- 标准库集成 libc,但不依赖它 - 可选类型代替 `null`,详见 [计算机科学中最严重的错误](https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/) - 编译期(可以简单看作在编译时执行的函数)执行实现泛型和反射 - 无需 FFI/bindings 的 C 库集成 @@ -46,7 +46,7 @@ showVersion: false _Zig 会要求你显式传递和管理你的内存,并且编译时就会跟踪你的内存是否发生泄漏, 高明的可选类型(这和 rust 的 option 有异曲同工之妙),强大的编译期运行,你可实现很多花哨的操作,而构建系统则被很多 C 项目拿去作为工具链使用_ -## 了解更多 ? +## 了解更多? 查看[这里](appendix/well-known-lib.html),列出了一些积极维护的 zig 库或者实现 diff --git a/course/more/atomic.md b/course/more/atomic.md index d1ceceab..20e06ae1 100644 --- a/course/more/atomic.md +++ b/course/more/atomic.md @@ -90,7 +90,7 @@ outline: deep ) ?T ``` -弱原子的比较与交换操作,如果目标指针是给定值,那么赋值为参数的新值,并返回null,否则仅读取值返回。 +弱原子的比较与交换操作,如果目标指针是给定值,那么赋值为参数的新值,并返回 null,否则仅读取值返回。 ### [`@cmpxchgStrong`](https://ziglang.org/documentation/master/#cmpxchgStrong) @@ -107,7 +107,7 @@ outline: deep ) ?T ``` -强原子的比较与交换操作,如果目标指针是给定值,那么赋值为参数的新值,并返回null,否则仅读取值返回。 +强原子的比较与交换操作,如果目标指针是给定值,那么赋值为参数的新值,并返回 null,否则仅读取值返回。 ### [`@fence`](https://ziglang.org/documentation/master/#fence) diff --git a/course/more/reflection.md b/course/more/reflection.md index c1a79560..eeadea18 100644 --- a/course/more/reflection.md +++ b/course/more/reflection.md @@ -10,7 +10,7 @@ outline: deep ## 观察已有类型 -zig 提供了不少函数来获取已有类型的信息,如:`@TypeOf`、`@typeName`、`@typeInfo`、`@hasDecl`、`@hasField`、`@field`、`@fieldParentPtr`、`@call`。 +zig 提供了不少函数来获取已有类型的信息,如:`@TypeOf`、`@typeName`、`@typeInfo`、`@hasDecl`、`@hasField`、`@field`、`@fieldParentPtr`、`@call`。 ### `@TypeOf` @@ -64,7 +64,7 @@ main.T.Y <<<@/code/release/reflection.zig#typeInfo -需要注意的是,我们必须使用 `inline for` 才能编译通过,这是因为结构体的 **“字段类型”** [`std.builtin.Type.StructField`](https://ziglang.org/documentation/master/std/#std.builtin.Type.StructField)中的一个字段是 `comptime_int`类型,使得StructField没有运行时大小,从而不能在运行时遍历其数组,必须用 `inline for` 在编译期计算。 +需要注意的是,我们必须使用 `inline for` 才能编译通过,这是因为结构体的 **“字段类型”** [`std.builtin.Type.StructField`](https://ziglang.org/documentation/master/std/#std.builtin.Type.StructField)中的一个字段是 `comptime_int`类型,使得 StructField 没有运行时大小,从而不能在运行时遍历其数组,必须用 `inline for` 在编译期计算。 ::: warning @@ -72,11 +72,11 @@ main.T.Y ::: -在以下示例中,使用 `@typeInfo` 获得一个整数类型的长度,并返回和它的长度相同的`u8`数组类型。当位数不为8的整倍数时,产生一个编译错误。 +在以下示例中,使用 `@typeInfo` 获得一个整数类型的长度,并返回和它的长度相同的`u8`数组类型。当位数不为 8 的整倍数时,产生一个编译错误。 <<<@/code/release/reflection.zig#TypeInfo2 -在以下示例中,使用 `@typeInfo` 获得一个结构体的信息,并使用 `@Type` 构造一个新的类型。构造的新结构体类型和原结构体的字段名和顺序相同,但结构体的内存布局被改为 extern,且每个字段的对齐被改为1。 +在以下示例中,使用 `@typeInfo` 获得一个结构体的信息,并使用 `@Type` 构造一个新的类型。构造的新结构体类型和原结构体的字段名和顺序相同,但结构体的内存布局被改为 extern,且每个字段的对齐被改为 1。 <<<@/code/release/reflection.zig#TypeInfo3 diff --git a/course/more/style_guide.md b/course/more/style_guide.md index 616a7eb2..bef0155e 100644 --- a/course/more/style_guide.md +++ b/course/more/style_guide.md @@ -22,7 +22,7 @@ outline: deep 简单来说,使用 **驼峰命名法**、**TitleCase 命名法**、**蛇形命名法** -- 类型声明使用 _TitleCase 命名法_(除非是一个 0 字段的 `struct`,此时它被视为一个命名空间,应使用 _蛇形命名法_ ) +- 类型声明使用 _TitleCase 命名法_(除非是一个 0 字段的 `struct`,此时它被视为一个命名空间,应使用 _蛇形命名法_) - 如果 `x` 是可以被调用的,并且它返回一个类型,那么使用 _TitleCase 命名法_ - 如果 `x` 是可被调用,并且返回非类型,应使用 _驼峰命名法_ - 其他情况下,应该使用 _蛇形命名法_ diff --git a/course/more/undefined_behavior.md b/course/more/undefined_behavior.md index 226cd086..b5dac658 100644 --- a/course/more/undefined_behavior.md +++ b/course/more/undefined_behavior.md @@ -11,7 +11,7 @@ zig 本身有许多未定义行为,它们可以很方便地帮助开发者找 > [!WARNING] > 注意:本章节并没有 CI 检查,故可能存在内容过期的情况,具体可参考 [官方手册](https://ziglang.org/documentation/master/#Undefined-Behavior)。 -安全检查会在debug、ReleaseSafe 模式下开启,但可以使用 [`@setRuntimeSafety`](https://ziglang.org/documentation/master/#setRuntimeSafety) 来强制指定在单独的块中是否开启安全检查(这将忽略构建模式)。 +安全检查会在 debug、ReleaseSafe 模式下开启,但可以使用 [`@setRuntimeSafety`](https://ziglang.org/documentation/master/#setRuntimeSafety) 来强制指定在单独的块中是否开启安全检查(这将忽略构建模式)。 当出现安全检查失败时,zig 会编译失败并触发堆栈跟踪: diff --git a/course/more/zero-type.md b/course/more/zero-type.md index c0cd2b50..b2e1b509 100644 --- a/course/more/zero-type.md +++ b/course/more/zero-type.md @@ -6,7 +6,7 @@ outline: deep 在 zig 中,有一些类型是特殊的零位类型(**Zero Type**),它们的大小是 0 bit。 -它们的特点是,涉及到它们的值不会出现在构建结果中(0 bit不占任何空间)。 +它们的特点是,涉及到它们的值不会出现在构建结果中(0 bit 不占任何空间)。 ## `void` diff --git a/course/prologue.md b/course/prologue.md index bf2d8827..db5d996c 100644 --- a/course/prologue.md +++ b/course/prologue.md @@ -15,15 +15,15 @@ Zig 这门语言并不适合计算机初学者,如果你已经对计算机有 有过多营销号说 zig 已经是 C 的替代品了,这是完全不正确的。将来或许会是,但现在肯定不是,目前 zig 只是一个有那么一丁点热度的高级语言。 -你可能会疑惑,为什么要再学习一门如此 `low level` 的语言, C 难道不好吗? +你可能会疑惑,为什么要再学习一门如此 `low level` 的语言,C 难道不好吗? C 很好,非常好,它非常成功,以至于 C 现在已经不再是一门语言,而是一个标准。 -你可能会注意到,现在跨语言调用,基本都是遵循的C ABI,包括编译出来的各种库供其他语言使用,也都是 C 可以使用的动态链接库。 +你可能会注意到,现在跨语言调用,基本都是遵循的 C ABI,包括编译出来的各种库供其他语言使用,也都是 C 可以使用的动态链接库。 -但由于历史原因,C 到现在已经处于一种较为割裂的存在,它本身有着一套自己的标准,但是不同的编译器却有着不同的“专属语法”,也就是不同编译器支持的语法实际上是 C 的超集!同时 C 本身没有一个属于自己的包管理器,各式各样的第三方包管理器。。。五花八门,像meson、cmake、xmake、vcpkg,而且均有上手难度。 +但由于历史原因,C 到现在已经处于一种较为割裂的存在,它本身有着一套自己的标准,但是不同的编译器却有着不同的“专属语法”,也就是不同编译器支持的语法实际上是 C 的超集!同时 C 本身没有一个属于自己的包管理器,各式各样的第三方包管理器。。。五花八门,像 meson、cmake、xmake、vcpkg,而且均有上手难度。 -历史上有不少语言都自诩是 C 的替代品,像Odin、Ada、Modula-2、Go,他们在某种程度上都算是失败了,当然 Zig 的未来也可能是这样子,成为一个不是C的替代品,单独的一门语言,或许有人使用。但就现在来看,我认为 Zig 还是很有希望成为 C 的代替品的,目前的语法均是围绕着语义明确化,减少隐式的执行,更高效的错误跟踪。 +历史上有不少语言都自诩是 C 的替代品,像 Odin、Ada、Modula-2、Go,他们在某种程度上都算是失败了,当然 Zig 的未来也可能是这样子,成为一个不是 C 的替代品,单独的一门语言,或许有人使用。但就现在来看,我认为 Zig 还是很有希望成为 C 的代替品的,目前的语法均是围绕着语义明确化,减少隐式的执行,更高效的错误跟踪。 -或许可能有人会跟我说 Rust 比 Zig 好,我要说的是你说的基本是对的,目前情况来看,Rust 的的确确比 Zig 好很多,更为完善的生态,更多能拿得出手的代表项目,以及相较 Zig 庞大很多的社区等等,但是在未来谁说的准呢? 更何况 Rust 和 Zig 并不是一个赛道上的东西,在我看来,Rust 的目标是 C++ 的替代, 因此我更愿意称之为“披着高抽象皮的 low level 语言”,Zig 的目标则是 C,而且目前 Zig 的特性也的确在这个方向发展。 +或许可能有人会跟我说 Rust 比 Zig 好,我要说的是你说的基本是对的,目前情况来看,Rust 的的确确比 Zig 好很多,更为完善的生态,更多能拿得出手的代表项目,以及相较 Zig 庞大很多的社区等等,但是在未来谁说的准呢?更何况 Rust 和 Zig 并不是一个赛道上的东西,在我看来,Rust 的目标是 C++ 的替代,因此我更愿意称之为“披着高抽象皮的 low level 语言”,Zig 的目标则是 C,而且目前 Zig 的特性也的确在这个方向发展。 Zig 的社区需要更多的人来构建,所以我写了这个文档,帮助新人来更好的理解和学习 Zig! diff --git a/course/update/0.12.0-description.md b/course/update/0.12.0-description.md index 28b0b47c..aefd4548 100644 --- a/course/update/0.12.0-description.md +++ b/course/update/0.12.0-description.md @@ -12,7 +12,7 @@ showVersion: false ::: info -注意: 存在一部分变动并未在本次的发行说明中提及,其中包括 API 的 `Break Change`。 +注意:存在一部分变动并未在本次的发行说明中提及,其中包括 API 的 `Break Change`。 ::: @@ -65,11 +65,11 @@ showVersion: false 78K ziglexer.js ``` -总输出大小为 **47M**,经过gzip处理后为 **5.7M**! +总输出大小为 **47M**,经过 gzip 处理后为 **5.7M**! - `src/Autodoc.zig` 用于处理 ZIR 代码(zig 编译时产生的中间代码),输出 json 以便 js 使用,这就导致很多代码无法通过某些数据(这些数据很可能是无效的),重建 AST 语法树 -- `lib/docs/commonmark.js` 是一个第三方的 markdown 实现,但它的特性有点太多了,例如,我们并不希望在文档注释中使用HTML标签,因为这样会让源代码的注释无比丑陋,应当只渲染源代码和 markdown。 +- `lib/docs/commonmark.js` 是一个第三方的 markdown 实现,但它的特性有点太多了,例如,我们并不希望在文档注释中使用 HTML 标签,因为这样会让源代码的注释无比丑陋,应当只渲染源代码和 markdown。 - `lib/docs/ziglexer.js` 是 js 中针对 zig 的语义标记实现。事实上,zig 已经在标准库中公开了由 zig 实现的语义标记。有趣的是,**andrewrk** 看到这个东西被添加进来的时候应该两眼一黑,具体可以见 [Issue 16306](https://github.com/ziglang/zig/pull/16306) [Issue 16490](https://github.com/ziglang/zig/issues/16490) 。 @@ -101,7 +101,7 @@ showVersion: false 12M sources.tar ``` -总输出大小为: **12M**,经过gzip处理后为 **2.3M**! +总输出大小为:**12M**,经过 gzip 处理后为 **2.3M**! 可以看到,新的实现的代码和产物都很简洁,产物刚刚好只有 4 个文件,并且文件大小直接缩减到了 **1/4** 。 @@ -115,17 +115,17 @@ showVersion: false ### 携带标准库文档 -在 zig 的 `0.11.0` 中,zig 发行时会带有一个 `docs/std/` 目录,其中包含着旧autodoc 实现构建产物(足足 47M 大小)。 +在 zig 的 `0.11.0` 中,zig 发行时会带有一个 `docs/std/` 目录,其中包含着旧 autodoc 实现构建产物(足足 47M 大小)。 在本次重写中,直接删除这些构建产物,作为代替,提供了 `zig std` 命令,这允许使用自带的 autodoc 生成器来打开一个浏览器窗口查看文档说明,首次使用此命令时,会先执行一次针对 `lib/compiler/std-docs.zig` 的编译操作。 -HTTP 服务器会动态创建请求的文件,包括 main.wasm 重建(如果任何源文件发生更改)和构造 sources.tar ,这意味着在查看文档时,对文档文件或 autodoc 系统本身的任何源更改都会立即反映出来。在 URL 前面加上 /debug URL 会使用 WebAssembly 模块的调试版本。 +HTTP 服务器会动态创建请求的文件,包括 main.wasm 重建(如果任何源文件发生更改)和构造 sources.tar,这意味着在查看文档时,对文档文件或 autodoc 系统本身的任何源更改都会立即反映出来。在 URL 前面加上 /debug URL 会使用 WebAssembly 模块的调试版本。 这意味着贡献者可以通过在浏览器窗口中按刷新来测试对 Zig 标准库文档以及 autodocs 功能的更改,只需要 Zig 的二进制发行版。 -总之,这使的zig的安装大小从 317M 减少到了 268M (-15%)。 +总之,这使的 zig 的安装大小从 317M 减少到了 268M(-15%)。 -编译器的 ReleaseSmall 版本从 10M 缩小到 9.8M (-1%)。 +编译器的 ReleaseSmall 版本从 10M 缩小到 9.8M(-1%)。 ### 构建文档时间 @@ -207,7 +207,7 @@ Benchmark 2 (26 runs): zig-0.12.0 build-exe hello.zig -fno-llvm -fno-lld branch_misses 7.20M ± 30.2K 7.15M … 7.28M 2 ( 8%) ⚡- 79.6% ± 4.4% ``` -当为 `x86_64` 目标编译时,可以通过传递 CLI 选项 `-fno-llvm -fno-lld`,或者在 `std.Build.Step.Compile` 上设置构建系统标志 `use_llvm` 和 `use_lld` 为 `false` 来访问这个后端。这个后端现在能够编译许多Zig项目,包括编译器本身。 +当为 `x86_64` 目标编译时,可以通过传递 CLI 选项 `-fno-llvm -fno-lld`,或者在 `std.Build.Step.Compile` 上设置构建系统标志 `use_llvm` 和 `use_lld` 为 `false` 来访问这个后端。这个后端现在能够编译许多 Zig 项目,包括编译器本身。 直到使用它作为默认后端前的任务: @@ -217,7 +217,7 @@ Benchmark 2 (26 runs): zig-0.12.0 build-exe hello.zig -fno-llvm -fno-lld ## Windows 资源 -Zig 现在支持编译(和交叉编译)Windows资源脚本(`.rc`文件)和 `.manifest` 文件,并将结果`.res` 文件链接到 PE/COFF 二进制文件的资源表中。 +Zig 现在支持编译(和交叉编译)Windows 资源脚本(`.rc`文件)和 `.manifest` 文件,并将结果`.res` 文件链接到 PE/COFF 二进制文件的资源表中。 - [Add a .rc -> .res compiler to the Zig compiler](https://github.com/ziglang/zig/pull/17069) - [Add zig rc subcommand, a (cross-platform) drop-in replacement for rc.exe](https://github.com/ziglang/zig/pull/17412) @@ -280,11 +280,11 @@ Zig 目前仍不成熟,即使是使用 `0.12.0` 也可能需要参与 zig 开 当前发布的新版本已经更新至 LLVM 17.0.6! -Zig 现在直接生成 LLVM bitcode 模块文件,然后将这些文件传递给 LLVM 。这意味着一个没有 LLVM 库的 Zig 编译器仍然可以生成 .bc 文件,然后这些文件可以传递给 clang 进行编译。 +Zig 现在直接生成 LLVM bitcode 模块文件,然后将这些文件传递给 LLVM。这意味着一个没有 LLVM 库的 Zig 编译器仍然可以生成 .bc 文件,然后这些文件可以传递给 clang 进行编译。 ### musl 1.2.4 -尽管musl v1.2.5 现在在上游可用,但这个版本的 Zig 仍然提供 v1.2.4 。预计 Zig 的下一个版本将使用新的的 musl。 +尽管 musl v1.2.5 现在在上游可用,但这个版本的 Zig 仍然提供 v1.2.4。预计 Zig 的下一个版本将使用新的的 musl。 ### glibc 2.38 @@ -318,7 +318,7 @@ Zig 现在直接生成 LLVM bitcode 模块文件,然后将这些文件传递 - [取消问题](https://github.com/ziglang/zig/issues/5913)。 - 异步函数指针阻止了堆栈大小的知晓。 -这些问题是可以克服的,但需要时间,Zig团队目前正在关注其他优先事项。 +这些问题是可以克服的,但需要时间,Zig 团队目前正在关注其他优先事项。 ## 贡献者和赞助者名单 diff --git a/course/update/0.13.0-description.md b/course/update/0.13.0-description.md index f9644fee..c2524986 100644 --- a/course/update/0.13.0-description.md +++ b/course/update/0.13.0-description.md @@ -48,7 +48,7 @@ Windows 不支持 `RPATH`,默认情况下仅在少量预定路径中搜索 DLL > b.installArtifact(sdl3_lib); > ``` > -> 构建结果: +> 构建结果: > > ```sh > zig-out/ @@ -77,7 +77,7 @@ Windows 不支持 `RPATH`,默认情况下仅在少量预定路径中搜索 DLL 当涉及到即使不写入终端时也强制输出颜色的任务时,存在两个标准:`CLICOLOR_FORCE` 和 `FORCE_COLOR`。这两个标准都没有像 `NO_COLOR` 那样普遍存在,但它们都有一定的优先级,并且受到一部分 CLI 工具的尊重。 -在 [`e45d24c`](https://github.com/ziglang/zig/commit/e45d24c0de29eb6668e56ea927e15505674833a6) 之前,Zig 使用 ZIG_DEBUG_COLOR 环境变量强制颜色输出,但该提交将其更改为 YES_COLOR 。 +在 [`e45d24c`](https://github.com/ziglang/zig/commit/e45d24c0de29eb6668e56ea927e15505674833a6) 之前,Zig 使用 ZIG_DEBUG_COLOR 环境变量强制颜色输出,但该提交将其更改为 YES_COLOR。 `YES_COLOR` 似乎目前在软件中几乎没有先例([在 GitHub 上搜索 `/(?-i)\bYES_COLOR\b/` 返回了 142 个文件](https://github.com/search?q=%2F%28%3F-i%29%5CbYES_COLOR%5Cb%2F&type=code))。 diff --git a/course/update/upgrade-0.12.0.md b/course/update/upgrade-0.12.0.md index 31a35a15..0fcce062 100644 --- a/course/update/upgrade-0.12.0.md +++ b/course/update/upgrade-0.12.0.md @@ -35,7 +35,7 @@ docgen_tmp/unnecessary_var.zig:3:9: note: consider using 'const' ::: info -结果位置语义是Zig语言中的一个特性,它影响函数如何返回结果和错误。 +结果位置语义是 Zig 语言中的一个特性,它影响函数如何返回结果和错误。 ::: @@ -86,11 +86,11 @@ const x, const y = .{ 42, runtime }; ### 命名空间类型等价性 -在Zig中,结构体(`struct`)、枚举(`enum`)、联合体(`union`)和不透明类型(`opaque types`)是特殊的,它们不像元组和数组那样使用结构等价性,而是创建独特的类型。这些类型有命名空间,因此可能包含声明,它们可以统称为"命名空间类型"。 +在 Zig 中,结构体(`struct`)、枚举(`enum`)、联合体(`union`)和不透明类型(`opaque types`)是特殊的,它们不像元组和数组那样使用结构等价性,而是创建独特的类型。这些类型有命名空间,因此可能包含声明,它们可以统称为"命名空间类型"。 在 `0.11.0` 版本中,每次这样的类型声明被语义分析时,都会创建一个新的类型。泛型类型的等价性是通过对编译时函数调用的记忆化(memoization)来处理的;也就是说,`std.ArrayList(u8) == std.ArrayList(u8)` 成立,因为 `ArrayList` 函数只被调用一次,其结果被记忆化。 -在0.12.0版本中,这一点发生了变化。现在,命名空间类型基于两个因素进行去重:它们的源位置和它们的捕获。 +在 0.12.0 版本中,这一点发生了变化。现在,命名空间类型基于两个因素进行去重:它们的源位置和它们的捕获。 类型的"捕获"指的是它闭包覆盖的编译时已知类型和值的集合。换句话说,它是在类型内部引用但在类型外部声明的值的集合。例如,`std.ArrayList` 的编译时 `T: type` 参数被它返回的类型捕获。如果两个命名空间类型由同一段代码声明并且有相同的捕获,那么它们现在被认为是完全相同的类型。 @@ -173,7 +173,7 @@ docgen_tmp/comptime_var_ptr_runtime_arg.zig:3:14: note: comptime var pointers ar 现在,这个测试也会发出一个编译错误。`load` 的调用发生在运行时,它的 `ptr` 参数没有标记为 `comptime`,所以在 `load` 的主体内,`ptr` 是运行时已知的。这意味着调用 `load` 使得指针 `&x` 在运行时已知,因此产生了编译错误。 -这个限制是为了修复一些反直觉的错误。当一个指向comptime var的指针变为运行时已知时,对它的修改变得无效,因为指向的数据变为常量,但类型系统没有反映这一点,导致在看似有效的代码中可能出现运行时段错误。此外,你在运行时从这样的指针读取的值将是它的"最终"编译时值,这是一种不直观的行为。因此,这些指针不能再是运行时已知的。 +这个限制是为了修复一些反直觉的错误。当一个指向 comptime var 的指针变为运行时已知时,对它的修改变得无效,因为指向的数据变为常量,但类型系统没有反映这一点,导致在看似有效的代码中可能出现运行时段错误。此外,你在运行时从这样的指针读取的值将是它的"最终"编译时值,这是一种不直观的行为。因此,这些指针不能再是运行时已知的。 第二个新的限制是一个指向 `comptime var` 的指针永远不允许包含在全局声明的解析值中。例如: @@ -220,7 +220,7 @@ referenced by: remaining reference traces hidden; use '-freference-trace' to see all reference traces ``` -这段代码引发的编译错误与前一个例子相同。这个限制主要是为了帮助在Zig编译器中实现增量编译,这依赖于全局声明的分析是顺序无关的,以及声明之间的依赖关系可以被轻易地建模。 +这段代码引发的编译错误与前一个例子相同。这个限制主要是为了帮助在 Zig 编译器中实现增量编译,这依赖于全局声明的分析是顺序无关的,以及声明之间的依赖关系可以被轻易地建模。 这种情况最常见的表现形式是在现有代码中出现编译错误,如果一个函数在编译时构造一个切片,然后在运行时使用。例如,考虑以下代码: @@ -247,7 +247,7 @@ referenced by: remaining reference traces hidden; use '-freference-trace' to see all reference traces ``` -调用getName返回一个切片,其ptr字段是一个指向comptime var的指针。这意味着这个值不能在运行时使用,也不能出现在全局声明的值中。这段代码可以通过在填充缓冲区后将计算的数据提升为const来修复: +调用 getName 返回一个切片,其 ptr 字段是一个指向 comptime var 的指针。这意味着这个值不能在运行时使用,也不能出现在全局声明的值中。这段代码可以通过在填充缓冲区后将计算的数据提升为 const 来修复: ```zig fn getName() []const u8 { @@ -262,7 +262,7 @@ test getName { } ``` -像在Zig的早期版本中一样,编译时已知的consts具有无限的生命周期,这里讨论的限制不适用于它们。因此,这段代码会正常运行。 +像在 Zig 的早期版本中一样,编译时已知的 consts 具有无限的生命周期,这里讨论的限制不适用于它们。因此,这段代码会正常运行。 另一种可能的失败模式是在使用旧语义创建全局可变编译时状态的代码中。例如,以下片段试图创建一个全局的编译时计数器: @@ -286,7 +286,7 @@ referenced by: remaining reference traces hidden; use '-freference-trace' to see all reference traces ``` -这段代码在 Zig `0.12.0` 中会发出一个编译错误。Zig不支持也不会支持这种用例:任何可变的编译时状态必须在本地表示。 +这段代码在 Zig `0.12.0` 中会发出一个编译错误。Zig 不支持也不会支持这种用例:任何可变的编译时状态必须在本地表示。 ### `@fieldParentPtr` @@ -380,7 +380,7 @@ test "@abs on int" { 在 Windows 上,程序的命令行参数是一个单一的 WTF-16 编码字符串,由程序来将其分割成字符串数组。在 C/C++ 中,C 运行时的入口点负责分割命令行并将 argc/argv 传递给 main 函数。 -以前,`ArgIteratorWindows` 匹配 `CommandLineToArgvW` 的行为,但事实证明,CommandLineToArgvW 的行为并不匹配 2008 年后的 C 运行时。在 2008 年,C 运行时的 argv 分割[改变了它如何处理引用参数中的连续双引号](https://daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESDOC)(现在被认为是转义引号,例如 `"foo""bar"` 在2008年后会被解析成 `foo"bar`),并且 `argv[0]` 的规则也被改变了。 +以前,`ArgIteratorWindows` 匹配 `CommandLineToArgvW` 的行为,但事实证明,CommandLineToArgvW 的行为并不匹配 2008 年后的 C 运行时。在 2008 年,C 运行时的 argv 分割[改变了它如何处理引用参数中的连续双引号](https://daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESDOC)(现在被认为是转义引号,例如 `"foo""bar"` 在 2008 年后会被解析成 `foo"bar`),并且 `argv[0]` 的规则也被改变了。 这个版本使 ArgIteratorWindows 匹配 2008 年后的 C 运行时的行为。这里的动机大致与 Rust 做出同样的改变时相同,即(改述): @@ -390,7 +390,7 @@ test "@abs on int" { 此外,对 [BatBadBut](https://flatt.tech/research/posts/batbadbut-you-cant-securely-execute-commands-on-windows/) 的建议的缓解措施依赖于 2008 年后的 argv 分割行为,以便对给 cmd.exe 的参数进行往返处理。 -[BadBatBut 的缓解措施](https://github.com/ziglang/zig/pull/19698)没有在0.12.0版本的发布截止日期之前完成。 +[BadBatBut 的缓解措施](https://github.com/ziglang/zig/pull/19698)没有在 0.12.0 版本的发布截止日期之前完成。 ### 不在允许覆盖 POSIX API @@ -431,7 +431,7 @@ Zig 0.12.0 用基于 Ryu 的算法替换了先前的 errol 浮点数格式化算 差异: -- 指数不再用前导 0 填充到 2 位,如果是正数,不再打印符号: +- 指数不再用前导 0 填充到 2 位,如果是正数,不再打印符号: ```sh errol: 2.0e+00 @@ -474,20 +474,20 @@ ryu: 2e0 | ryu_exp: 1.981e-40 ``` -性能:约提高2.3倍 +性能:约提高 2.3 倍 -代码大小:大约增加5KB(2倍) +代码大小:大约增加 5KB(2 倍) 以上源代码:[Github](https://github.com/ziglang/zig/pull/19229) -### 重构HTTP +### 重构 HTTP 首先,一些非常直接的更改: - 不发出 Server HTTP 头。如果用户希望添加,让他们自己添加。这不是严格必要的,可以说是一个有害的默认设置。 - 修正 `finish` 的错误集,不再包含 NotWriteable 和 MessageTooLong 在 Server 中防止零长度的块 -- 在 FetchOptions 中添加缺失的重定向行为选项,并将其改为枚举,而不是2个字段 +- 在 FetchOptions 中添加缺失的重定向行为选项,并将其改为枚举,而不是 2 个字段 - `error.CompressionNotSupported` 被重命名为 `error.CompressionUnsupported`,与同一集合中所有其他错误的命名约定相匹配。 - 删除了与字段和类型名称重复的文档注释。 - 暂时禁用服务器中的 zstd 解压缩;参见 [#18937](https://github.com/ziglang/zig/issues/18937)。 @@ -503,7 +503,7 @@ ryu: 2e0 http_proxy 和 https_proxy 字段现在是指针,因为它们通常未被填充。 -将 `loadDefaultProxies` 改为 `initDefaultProxies` ,以表明它实际上并未从磁盘或网络加载任何东西。现在的函数是有泄漏的;API用户必须传递一个已经实例化的竞技场分配器。消除了反初始化代理的需要。 +将 `loadDefaultProxies` 改为 `initDefaultProxies` ,以表明它实际上并未从磁盘或网络加载任何东西。现在的函数是有泄漏的;API 用户必须传递一个已经实例化的竞技场分配器。消除了反初始化代理的需要。 以前,代理存储了任意的头部集合。现在它们只存储授权值。 @@ -575,9 +575,9 @@ pub fn serve( ### deflate 的重实现 -> deflat e是一种无损数据压缩算法和相关的文件格式。它通常用于 gzip 和 zip 文件格式中,也是 HTTP 协议中的一种常见的内容编码方式。 +> deflat e 是一种无损数据压缩算法和相关的文件格式。它通常用于 gzip 和 zip 文件格式中,也是 HTTP 协议中的一种常见的内容编码方式。 > -> inflate 是一种数据解压缩算法,它是 deflate 压缩算法的反向操作。在网络传输或数据存储中,通常先使用 deflate 算法将数据压缩,然后在需要使用数据时,再使用inflate算法将数据解压缩回原始形式。 +> inflate 是一种数据解压缩算法,它是 deflate 压缩算法的反向操作。在网络传输或数据存储中,通常先使用 deflate 算法将数据压缩,然后在需要使用数据时,再使用 inflate 算法将数据解压缩回原始形式。 在 `0.11.0` 中,deflate 实现是从 Go 标准库移植过来的,它有一些不受欢迎的特性,如不恰当地使用了全局变量,在 Zig 的代码库中关于 Go 的优化器的评论,以及需要动态内存分配。 @@ -587,7 +587,7 @@ pub fn serve( 新的代码对所有结构使用静态分配,不需要分配器。这对于 deflate 很有意义,因为所有的结构、内部缓冲区获得了大小刚好的内存。对于 inflate 来说,相较过去的实现通过不预分配到理论最大尺寸数组(申请的数组通常不会被完全使用)来减少内存使用。 -对于 deflate ,新的实现分配了 395K,而之前的实现使用了 779K。对于 inflate,新的实现分配了 74.5K,而旧的实现大约 36K。 +对于 deflate,新的实现分配了 395K,而之前的实现使用了 779K。对于 inflate,新的实现分配了 74.5K,而旧的实现大约 36K。 inflate 的差异是因为我们在这里使用 64K 的历史记录,而之前是 32K。 @@ -727,7 +727,7 @@ pub fn oldGzip(allocator: std.mem.Allocator) !void { - 整合 `std.c` 定义 - 为所有整数添加类型安全性 -例如,以前这样在tty上设置即时模式: +例如,以前这样在 tty 上设置即时模式: ```zig const in = std.io.getStdIn(); @@ -803,7 +803,7 @@ pub const tc_lflag_t = switch (native_arch) { }; ``` -许多其他的 `std.posix` API也以类似的方式进行了调整。 +许多其他的 `std.posix` API 也以类似的方式进行了调整。 ### `std.builtin` 枚举字段小写化 @@ -913,7 +913,7 @@ pub const Options = struct { ### 指针保护锁(Pointer Stability Locks) -> "Pointer Stability Locks" 是一种用于保护数据结构中的指针不被非法修改的机制。在Zig中,你可以使用 `std.debug.SafetyLock` 来锁定指针,防止它们在不应该被修改的时候被修改。如果尝试在锁定后修改这些指针,程序会抛出一个panic,而不是触发未定义的行为。这可以帮助开发者更容易地发现和修复可能的错误。 +> "Pointer Stability Locks" 是一种用于保护数据结构中的指针不被非法修改的机制。在 Zig 中,你可以使用 `std.debug.SafetyLock` 来锁定指针,防止它们在不应该被修改的时候被修改。如果尝试在锁定后修改这些指针,程序会抛出一个 panic,而不是触发未定义的行为。这可以帮助开发者更容易地发现和修复可能的错误。 添加了 `std.debug.SafetyLock` ,标准库的哈希表中新添加的 `lockPointers()` 和 `unlockPointers()` 用到了它。 @@ -1016,7 +1016,7 @@ fn calculate(m: anytype) i32 { ### 系统包模式 -通过引入系统集成选项,使zig构建系统对系统包维护者更加友好。 +通过引入系统集成选项,使 zig 构建系统对系统包维护者更加友好。 让我们使用 [groovebasin](https://github.com/andrewrk/groovebasin/tree/old-client) 作为示例项目来检查这个特性: diff --git a/course/update/upgrade-0.13.0.md b/course/update/upgrade-0.13.0.md index 25d8cdc3..d141346c 100644 --- a/course/update/upgrade-0.13.0.md +++ b/course/update/upgrade-0.13.0.md @@ -19,9 +19,9 @@ showVersion: false 移除了两个原始实现,转而采用基于算法类型的泛型实现。过去有三个很相似的实现,这令人在选择时感到迷惑! -库普曼多项式(Koopman polynomial)没有完全等价的多项式,因此已将其添加到catalog.txt 文件中。未来更新时测试会报告此问题。 +库普曼多项式(Koopman polynomial)没有完全等价的多项式,因此已将其添加到 catalog.txt 文件中。未来更新时测试会报告此问题。 -对于旧库普曼多项式 `api` 的用户来说,这是一个重大变化,特别是在使用自定义或非标准多项式时( Crc32 别名将继续起作用)。编译错误会说明需要做什么才能保留现有功能,可能需要用户进行少量代码更改。 +对于旧库普曼多项式 `api` 的用户来说,这是一个重大变化,特别是在使用自定义或非标准多项式时(Crc32 别名将继续起作用)。编译错误会说明需要做什么才能保留现有功能,可能需要用户进行少量代码更改。 ```zig const hash = Crc32WithPoly(.Castagnoli); // old @@ -150,7 +150,7 @@ try child.spawn(); 新实现的设计理念是,单个进程将直接控制终端,所有其他进度报告都将传回该进程,这可以按照需求随意定制进度条。 -创建一个标准的 “Zig Progress Protocol” 来使用,方便当应用程序是终端所有者或者当应用程序是子进程时,`std.Progress` API 都可以正常工作。后者的进度信息将通过管道以语义方式传递给父进程。 +创建一个标准的“Zig Progress Protocol”来使用,方便当应用程序是终端所有者或者当应用程序是子进程时,`std.Progress` API 都可以正常工作。后者的进度信息将通过管道以语义方式传递给父进程。 文件描述符通过 `ZIG_PROGRESS` 环境变量给出,方便 `std.process.Child` 与其集成,因此在父进程中附加子进程的进度就像在调用 `spawn` 之前设置 `child.progress_node` 字段一样简单。