Skip to content
Closed
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
23 changes: 23 additions & 0 deletions .github/workflows/autocorrect.yml
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 文件!
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
- 浮点的optimized说明,和关于向量浮点reduce的情况
- 浮点的 optimized 说明,和关于向量浮点 reduce 的情况
2 changes: 1 addition & 1 deletion course/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ showVersion: false

::: info 🅿️ 提示

本文档所使用的构建工具为 [bunjs](https://bun.sh/),在提交时请勿将其他nodejs的包管理工具的额外配置文件添加到仓库中
本文档所使用的构建工具为 [bunjs](https://bun.sh/),在提交时请勿将其他 nodejs 的包管理工具的额外配置文件添加到仓库中

:::
6 changes: 3 additions & 3 deletions course/advanced/assembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 语法兼容。

Expand Down Expand Up @@ -68,7 +68,7 @@ asm volatile ("assembly code"
);
```

结构大体是这样的:
结构大体是这样的

```asm
# 别忘记三个冒号,即便对应的部分不存在也需要有冒号
Expand All @@ -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`,它会通知编译器内联汇编会写入任意为声明的内存位置。

Expand Down
2 changes: 1 addition & 1 deletion course/advanced/comptime.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)。

:::

Expand Down
12 changes: 6 additions & 6 deletions course/advanced/interact-with-c.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` 文件中,

Expand All @@ -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"`,并且在需要使用动态库的时候也同样不能少。

:::

Expand Down Expand Up @@ -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 🅿️ 提示

Expand All @@ -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 的静态链接的二进制可执行文件:

Expand Down
8 changes: 4 additions & 4 deletions course/advanced/memory_manage.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ outline: deep

> zig 在内存管理方面采取了类似 C 的方案,完全由程序员管理内存,这也是为什么 zig 没有运行时开销的原因,同时这也是为什么 zig 可以在如此多环境(包括实时软件、操作系统内核、嵌入式设备和低延迟服务器)中无缝工作的原因。

事实上,在 C 开发中最难以调试的 bug 往往是由于错误的内存管理引起的, zig 在此基础上给我们提供了少量的保护,但仅仅是少量的保护,这就要求程序员在需要明白数据在内存中真实存在的模样(这就涉及到计算机组成原理和操作系统的理论知识了,当然还涉及到一点点的汇编知识)。
事实上,在 C 开发中最难以调试的 bug 往往是由于错误的内存管理引起的,zig 在此基础上给我们提供了少量的保护,但仅仅是少量的保护,这就要求程序员在需要明白数据在内存中真实存在的模样(这就涉及到计算机组成原理和操作系统的理论知识了,当然还涉及到一点点的汇编知识)。

事实上,zig 本身的标准库为我们提供了多种内存分配模型:

Expand Down Expand Up @@ -63,7 +63,7 @@ outline: deep

## `ArenaAllocator`

这个分配器的特点是你可以多次申请内存,并无需每次用完时进行 `free` 操作,可以使用 `deinit` 直接一次回收所有分发出去的内存,如果你的程序是一个命令行程序或者没有什么特别的循环模式,例如web server 或者游戏事件循环之类的,那么推荐你使用这个。
这个分配器的特点是你可以多次申请内存,并无需每次用完时进行 `free` 操作,可以使用 `deinit` 直接一次回收所有分发出去的内存,如果你的程序是一个命令行程序或者没有什么特别的循环模式,例如 web server 或者游戏事件循环之类的,那么推荐你使用这个。

<<<@/code/release/memory_manager.zig#ArenaAllocator

Expand Down Expand Up @@ -95,7 +95,7 @@ outline: deep

这是最基本的分配器,它仅仅是实现了不同系统的分页申请系统调用。

每次执行分配时,它都会向操作系统申请整个内存页面。单个字节的分配可能会剩下数千的字节无法使用(现代操作系统页大小最小为4K,但有些系统还支持2M和1G的页),由于涉及到系统调用,它的速度很慢,但好处是线程安全并且无锁。
每次执行分配时,它都会向操作系统申请整个内存页面。单个字节的分配可能会剩下数千的字节无法使用(现代操作系统页大小最小为 4K,但有些系统还支持 2M 和 1G 的页),由于涉及到系统调用,它的速度很慢,但好处是线程安全并且无锁。

<<<@/code/release/memory_manager.zig#page_allocator

Expand All @@ -116,7 +116,7 @@ outline: deep
>
> 此外,由于内存块在物理上是相邻的,因此内存池还可以减少内存碎片。
>
> 内存池也有其缺点,例如,如果内存池的大小设置得不合适(太大或太小),则可能会浪费内存或导致内存不足。
> 内存池也有其缺点例如,如果内存池的大小设置得不合适(太大或太小),则可能会浪费内存或导致内存不足。

<<<@/code/release/memory_manager.zig#MemoryPool

Expand Down
8 changes: 4 additions & 4 deletions course/advanced/package_management.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand All @@ -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(
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions course/advanced/type_cast.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ zig 提供了三种类型转换,第一种是已知完全安全且不存在歧

出现时机:当需要一种类型时却提供了另一种类型,如果此时这种转换是安全,且不存在歧义,则会由 zig 自动完成。

仅当完全明确如何从一种类型转换为另一种类型并且保证转换安全时才允许自动转换,但有一个例外,那就是 zig 的 [C指针](https://ziglang.org/documentation/master/#C-Pointers)。
仅当完全明确如何从一种类型转换为另一种类型并且保证转换安全时才允许自动转换,但有一个例外,那就是 zig 的 [C 指针](https://ziglang.org/documentation/master/#C-Pointers)。

大致的规则如下:

Expand Down Expand Up @@ -50,15 +50,15 @@ 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`。

### 切片、数组、指针

1. 指向常量数组的指针,可以分配给元素为常量的切片,这在处理字符串时很有用。

<<<@/code/release/type-cast.zig#pointer_arr_slice_1

2. 允许直接将数组的指针赋值给切片(会被自动转换),这会使切片长度直接等于数组。
2. 允许直接将数组的指针赋值给切片 (会被自动转换),这会使切片长度直接等于数组。

<<<@/code/release/type-cast.zig#pointer_arr_slice_2

Expand Down
10 changes: 5 additions & 5 deletions course/appendix/well-known-lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)**: 一个轻量强类型嵌入式语言
Expand All @@ -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 版本
Expand All @@ -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 代码
2 changes: 1 addition & 1 deletion course/basic/advanced_type/enum.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ outline: deep

## 枚举方法

没错,枚举也可以拥有方法,实际上枚举仅仅是一种命名空间(你可以看作是一类 struct )。
没错,枚举也可以拥有方法,实际上枚举仅仅是一种命名空间(你可以看作是一类 struct)。

<<<@/code/release/enum.zig#enum_with_method

Expand Down
Loading