diff --git a/content/contributing.smd b/content/contributing.smd index 2723ae6..6a1d5e8 100644 --- a/content/contributing.smd +++ b/content/contributing.smd @@ -44,7 +44,7 @@ zine - [ZigCC 网站](https://ziglang.cc) - [ZigCC 公众号](https://github.com/zigcc/.github/raw/main/zig_mp.png) -# [网站更新日志]($section.id('changelog')) +# [网站更新日志]($section.id('website-changelog')) - **2025-06-30:** 切换到 [zine](https://zine-ssg.io/) - **2024-08-18:** 切换主题 [docsy](https://github.com/google/docsy) diff --git a/content/learn/style-guide.smd b/content/learn/style-guide.smd index bacce52..934793d 100644 --- a/content/learn/style-guide.smd +++ b/content/learn/style-guide.smd @@ -74,7 +74,7 @@ fn read(stream: std.net.Stream) ![]const u8 { 我认为,这个规范并不能使代码可读性提高。在这个场景下,应该是开发者,而不是编译器,更有资格选择更有可读性的命名方案。 -# [命名规范]($section.id('naming-convention')) +# [命名规范]($section.id('naming-conventions')) 除了遵守以上这些规则以外,开发者可以自由地选择他们喜欢的命名规范。但是,理解 Zig 自身的命名规范是有益的,因为大部分你需要打交道的代码,如 Zig 标准库,或者其他三方库,都采用了 Zig 的命名规范。 diff --git a/content/monthly/202207.smd b/content/monthly/202207.smd index eaf2e29..348252b 100644 --- a/content/monthly/202207.smd +++ b/content/monthly/202207.smd @@ -28,7 +28,7 @@ before starting with Zig? : Zig](https://www.reddit.com/r/Zig/comments/w63x6r/is_it_necessary_to_know_c_or_another_systems/) -# [项目/工具]($section.id('项目/工具')) +# [项目/工具]($section.id('projects-and-tools')) - [Release bun v0.1.5 · oven-sh/bun](https://github.com/oven-sh/bun/releases/tag/bun-v0.1.5) diff --git a/content/monthly/202208.smd b/content/monthly/202208.smd index 841eaf3..86472ea 100644 --- a/content/monthly/202208.smd +++ b/content/monthly/202208.smd @@ -47,7 +47,7 @@ ![](/images/blockly.webp) -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2022-08-01..2022-09-01) +# [Zig 语言更新]($section.id('zig-language-updates')) - [make self-hosted the default compiler by andrewrk · Pull Request \#12368](https://github.com/ziglang/zig/pull/12368) Master diff --git a/content/monthly/202209.smd b/content/monthly/202209.smd index 1795eaf..05e1dfc 100644 --- a/content/monthly/202209.smd +++ b/content/monthly/202209.smd @@ -126,4 +126,4 @@ Zig,笔者觉得大概率就是本次争论的观点,Rust - [stm32f4.zig](https://github.com/moonxraccoon/stm32f4.zig) STM32F4(ARM Cortex M4 的高性能 32 位微控制器) 固件抽象层 -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?q=+is%3Aclosed+is%3Apr+closed%3A2022-09-01..2022-10-01+) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202210.smd b/content/monthly/202210.smd index 925b42c..2aafcc6 100644 --- a/content/monthly/202210.smd +++ b/content/monthly/202210.smd @@ -55,4 +55,4 @@ - [A minimal RocksDB example with Zig](https://notes.eatonphil.com/zigrocks.html) -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2022-10-01..2022-11-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202211.smd b/content/monthly/202211.smd index 5b1435c..508d63c 100644 --- a/content/monthly/202211.smd +++ b/content/monthly/202211.smd @@ -114,4 +114,4 @@ const Animal = union(enum){ - [Zig Support plugin for IntelliJ and CLion version 0.2.0 released](https://zig.news/marioariasc/zig-support-plugin-for-intellij-and-clion-version-020-released-3g06) -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2022-11-01..2022-12-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202212.smd b/content/monthly/202212.smd index e571d32..a11fd37 100644 --- a/content/monthly/202212.smd +++ b/content/monthly/202212.smd @@ -13,4 +13,4 @@ # [项目/工具]($section.id('项目/工具')) -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2022-12-01..2023-01-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202301.smd b/content/monthly/202301.smd index 7fb1cf9..6cedc36 100644 --- a/content/monthly/202301.smd +++ b/content/monthly/202301.smd @@ -98,4 +98,4 @@ Zig library for HyperLogLog estimation [This Week In Zig](https://thisweekinzig.mataroa.blog/) 一个介绍 Zig 的周刊,主要是 master 分支上的改动 -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-01-01..2023-02-01) +# [[Zig 语言更新]($section.id('zig-language-updates'))](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-01-01..2023-02-01) diff --git a/content/monthly/202302.smd b/content/monthly/202302.smd index 12527f1..9b8b96a 100644 --- a/content/monthly/202302.smd +++ b/content/monthly/202302.smd @@ -110,4 +110,4 @@ build,让构建不再那么痛苦。 - [Writing high-performance clients for TigerBeetle](https://tigerbeetle.com/blog/2023-02-21-writing-high-performance-clients-for-tigerbeetle/) -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-02-01..2023-03-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202303.smd b/content/monthly/202303.smd index 05a3771..e77971c 100644 --- a/content/monthly/202303.smd +++ b/content/monthly/202303.smd @@ -80,7 +80,7 @@ Tiny desktop utility to keep notes [ringtailsoftware/zig-wasm-audio-framebuffer](https://github.com/ringtailsoftware/zig-wasm-audio-framebuffer) Examples of integrating Zig and Wasm for audio and graphics on the web -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-03-01..2023-04-01) +# [[Zig 语言更新]($section.id('zig-language-updates'))](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-03-01..2023-04-01) [zig build: run steps in parallel \#14647](https://github.com/ziglang/zig/pull/14647) diff --git a/content/monthly/202304.smd b/content/monthly/202304.smd index dee548b..0360985 100644 --- a/content/monthly/202304.smd +++ b/content/monthly/202304.smd @@ -106,4 +106,4 @@ Zvisor is an open-source hypervisor written in the Zig programming language, which provides a modern and efficient approach to systems programming. -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-04-01..2023-05-01) +# [[Zig 语言更新]($section.id('zig-language-updates'))](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-04-01..2023-05-01) diff --git a/content/monthly/202305.smd b/content/monthly/202305.smd index 7654cd0..690788d 100644 --- a/content/monthly/202305.smd +++ b/content/monthly/202305.smd @@ -100,4 +100,4 @@ A 2048 game to run in terminal [mitchellh/zig](https://github.com/mitchellh/zig-objc) Objective-C runtime bindings for Zig (Zig calling ObjC). -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-04-01..2023-05-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202306.smd b/content/monthly/202306.smd index cb8a897..3505132 100644 --- a/content/monthly/202306.smd +++ b/content/monthly/202306.smd @@ -184,7 +184,7 @@ Shell completions for the Zig compiler. [menduz/zig](https://github.com/menduz/zig-steamworks) Steamwork bindings for Zig. -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-05-01..2023-06-01) +# [[Zig 语言更新]($section.id('zig-language-updates'))](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-05-01..2023-06-01) - [WASI: Implement experimental threading support by Luukdegram · Pull Request \#16207 · diff --git a/content/monthly/202307.smd b/content/monthly/202307.smd index 39f898e..b67a8af 100644 --- a/content/monthly/202307.smd +++ b/content/monthly/202307.smd @@ -147,4 +147,4 @@ Experimental operating system written in Zig [EugenHotaj/zig_gpt2](https://github.com/EugenHotaj/zig_gpt2) GPT-2 inference engine written in Zig -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-06-01..2023-07-01) +# [[Zig 语言更新]($section.id('zig-language-updates'))](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-06-01..2023-07-01) diff --git a/content/monthly/202308.smd b/content/monthly/202308.smd index c8567ff..dc1ddee 100644 --- a/content/monthly/202308.smd +++ b/content/monthly/202308.smd @@ -227,4 +227,4 @@ Andrew 的最新文章,远离社交平台! - [Mach v0.2 released](https://devlog.hexops.com/2023/mach-v0.2-released/) -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-07-01..2023-08-01) +# [[Zig 语言更新]($section.id('zig-language-updates'))](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-07-01..2023-08-01) diff --git a/content/monthly/202309.smd b/content/monthly/202309.smd index 52332bb..887d632 100644 --- a/content/monthly/202309.smd +++ b/content/monthly/202309.smd @@ -114,7 +114,7 @@ Reactive signal/Dependency tracking library in Zig. [buzz-language/buzz](https://github.com/buzz-language/buzz) A small/lightweight statically typed scripting language -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-08-01..2023-09-01) +# [Zig 语言更新]($section.id('zig-language-updates')) [Aro translate](https://github.com/ziglang/zig/pull/17221) 用 Zig 写的 [Aro](https://github.com/Vexu/arocc) 来替换 clang,来实现 diff --git a/content/monthly/202310.smd b/content/monthly/202310.smd index 0bafef5..1f01a08 100644 --- a/content/monthly/202310.smd +++ b/content/monthly/202310.smd @@ -115,4 +115,4 @@ Enable the use of Zig code in JavaScript project Language server for GLSL (autocomplete, goto-definition, formatter, and more) -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-09-01..2023-10-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202311.smd b/content/monthly/202311.smd index 78d02ff..cd9cbfb 100644 --- a/content/monthly/202311.smd +++ b/content/monthly/202311.smd @@ -155,4 +155,4 @@ Fields [akhildevelops/cudaz](https://github.com/akhildevelops/cudaz) A Zig Cuda wrapper -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2023-10-01..2023-11-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202402.smd b/content/monthly/202402.smd index 2e05929..0f3a554 100644 --- a/content/monthly/202402.smd +++ b/content/monthly/202402.smd @@ -94,4 +94,4 @@ Zig-TypeScript binding generator 🟦 🦎 [sneekyfoxx/ziggy](https://github.com/sneekyfoxx/ziggy) 又又一个 Zig 版本管理工具 -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2024-02-01..2023-03-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202403.smd b/content/monthly/202403.smd index 4049567..9ba188d 100644 --- a/content/monthly/202403.smd +++ b/content/monthly/202403.smd @@ -291,4 +291,4 @@ ability of running pipeline like bash. [zigcc/zig-milestone](https://github.com/zigcc/zig-milestone) Zig milstone monitor -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2024-02-01..2024-03-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202404.smd b/content/monthly/202404.smd index 098f207..6c990c4 100644 --- a/content/monthly/202404.smd +++ b/content/monthly/202404.smd @@ -124,4 +124,4 @@ Zig string library that includes small string optimization on the stack [FalsePattern/ZigBrains](https://github.com/FalsePattern/ZigBrains) Yet another zig language plugin for intellij -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2024-04-01..2024-05-01) +[Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202405.smd b/content/monthly/202405.smd index a64929a..2f3dad6 100644 --- a/content/monthly/202405.smd +++ b/content/monthly/202405.smd @@ -96,4 +96,4 @@ A generic and general purpose Set implementation for the Zig language [akarpovskii/tuile](https://github.com/akarpovskii/tuile) A Text UI library for Zig -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2024-05-01..2024-06-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/202406.smd b/content/monthly/202406.smd index 0447060..64e80f7 100644 --- a/content/monthly/202406.smd +++ b/content/monthly/202406.smd @@ -166,4 +166,4 @@ Zig WebAssembly Runtime Engine io_uring like asynchronous API and coroutine powered IO tasks for zig -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2024-06-01..2024-07-01) +# [[Zig 语言更新]($section.id('zig-language-updates'))](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2024-06-01..2024-07-01) diff --git a/content/monthly/202407.smd b/content/monthly/202407.smd index 63234c2..d3e4dc8 100644 --- a/content/monthly/202407.smd +++ b/content/monthly/202407.smd @@ -167,7 +167,7 @@ fn get_window_messages() [65536][:0]const u8 { - 在 JavaScript 允许您内联表达式的某些情况下,您可能需要分解出一个变量来澄清生存期。看看[这个问题](https://github.com/ziglang/zig/issues/12414)。 -# [项目/工具]($section.id('projects-tools')) +# [项目/工具]($section.id('projects-and-tools')) [18alantom/fex](https://github.com/18alantom/fex) A command-line file explorer prioritizing quick navigation. diff --git a/content/monthly/202410.smd b/content/monthly/202410.smd index d0b4b3b..1fd976a 100644 --- a/content/monthly/202410.smd +++ b/content/monthly/202410.smd @@ -129,4 +129,4 @@ Video editor 🎬 written in Zig ⚡ using raylib [pwbh/ymlz](https://github.com/pwbh/ymlz) Small and convenient yaml parser for Zig -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2024-10-01..2024-11-01) +# [[Zig 语言更新]($section.id('zig-language-updates'))](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2024-10-01..2024-11-01) diff --git a/content/monthly/202411.smd b/content/monthly/202411.smd index 55081fc..f59dd6d 100644 --- a/content/monthly/202411.smd +++ b/content/monthly/202411.smd @@ -151,4 +151,4 @@ PDF reader for terminal emulators using the Kitty image protocol [Dr-Nekoma/lyceum](https://github.com/Dr-Nekoma/lyceum) An MMO game written in Erlang (+ PostgreSQL) + Zig (+ Raylib) -# [Zig 语言更新](https://github.com/ziglang/zig/pulls?page=1&q=+is%3Aclosed+is%3Apr+closed%3A2024-11-01..2024-12-01) +# [Zig 语言更新]($section.id('zig-language-updates')) diff --git a/content/monthly/index.smd b/content/monthly/index.smd index 2621aff..4ac09af 100644 --- a/content/monthly/index.smd +++ b/content/monthly/index.smd @@ -12,4 +12,4 @@ 社区内的最新进展,信息来源:[Zig NEWS](https://zig.news/top/month)、[Zig monthly](https://zigmonthly.org/)、[Lobsters](https://lobste.rs/t/zig)、[Reddit](https://www.reddit.com/r/Zig/)、[Zig weekly -newsletter](https://discu.eu/weekly/zig/)、[Ziggit](https://ziggit.dev/)、[用户推荐](https://github.com/orgs/zigcc/discussions/new?category=%E4%BD%9C%E5%93%81%E5%88%86%E4%BA%AB) +newsletter](https://discu.eu/weekly/zig/)、[Ziggit](https://ziggit.dev/)、[用户推荐]($section.id('user-recommendations')) \ No newline at end of file diff --git a/content/post/2023-09-05-bog-gc-1-en.smd b/content/post/2023-09-05-bog-gc-1-en.smd index 238d2a7..32bc8dd 100644 --- a/content/post/2023-09-05-bog-gc-1-en.smd +++ b/content/post/2023-09-05-bog-gc-1-en.smd @@ -14,7 +14,7 @@ Bog is a small scripting language developed using Zig. Its GC design is inspired by a paper titled [An efficient of Non-Moving GC for Function languages](https://www.pllab.riec.tohoku.ac.jp/papers/icfp2011UenoOhoriOtomoAuthorVersion.pdf). -# [Overview]($section.id('Overview')) +# [Overview]($section.id('overview')) 1. Introduction - Design of the Heap diff --git a/content/post/2023-09-21-zig-midi.smd b/content/post/2023-09-21-zig-midi.smd index c79e869..6cac0ba 100644 --- a/content/post/2023-09-21-zig-midi.smd +++ b/content/post/2023-09-21-zig-midi.smd @@ -194,7 +194,7 @@ pub const Message = struct { - value 和 setValue 函数:用于获取和设置 MIDI 消息的值字段。 - Kind 枚举:定义了 MIDI 消息的所有可能种类,包括通道事件和系统事件。 -## [midi 消息结构]($section.id('midi 消息结构')) +## [midi 消息结构]($section.id('midi-message-structure')) 我们需要先了解 MIDI 消息的一些背景。 diff --git a/content/post/2023-12-24-zig-build-explained-part1.smd b/content/post/2023-12-24-zig-build-explained-part1.smd index 7fba69d..0a1fe6d 100644 --- a/content/post/2023-12-24-zig-build-explained-part1.smd +++ b/content/post/2023-12-24-zig-build-explained-part1.smd @@ -15,11 +15,11 @@ Zig 构建系统仍然缺少文档,对很多人来说,这是不使用它的 我们将从一个刚刚初始化的 Zig 项目开始,逐步深入到更复杂的项目。在此过程中,我们将学习如何使用库和软件包、添加 C 代码,甚至如何创建自己的构建步骤。 -# [免责声明]($section.id('免责声明')) +# [免责声明]($section.id('disclaimer')) 由于我不会解释 Zig 语言的语法或语义,因此我希望你至少已经有了一些使用 Zig 的基本经验。我还将链接到标准库源代码中的几个要点,以便您了解所有这些内容的来源。我建议你阅读编译系统的源代码,因为如果你开始挖掘编译脚本中的函数,大部分内容都不言自明。所有功能都是在标准库中实现的,不存在隐藏的构建魔法。 -# [开始]($section.id('开始')) +# [开始]($section.id('getting-started')) 我们通过新建一个文件夹来创建一个新项目,并在该文件夹中调用 zig init-exe。 @@ -56,7 +56,7 @@ pub fn build(b: *std.Build) void { } ``` -# [基础知识]($section.id('基础知识')) +# [基础知识]($section.id('basics')) 构建系统的核心理念是,Zig 工具链将编译一个 Zig 程序 (build.zig),该程序将导出一个特殊的入口点(`pub fn build(b: *std.build.Builder) void`),当我们调用 `zig build` 时,该入口点将被调用。 @@ -95,7 +95,7 @@ Step 遵循与 std.mem.Allocator 相同的接口模式,需要实现一个 make 现在,我们需要创建一个稍正式的 Zig 程序: -# [编译 Zig 源代码]($section.id('编译 Zig 源代码')) +# [编译 Zig 源代码]($section.id('compiling-zig-source-code')) 要使用编译系统编译可执行文件,编译器需要使用函数 Builder.addExecutable,它将为我们创建一个新的 LibExeObjStep。这个步骤实现是 zig build-exe、zig build-lib、zig build-obj 或 zig test 的便捷封装,具体取决于初始化方式。本文稍后将对此进行详细介绍。 @@ -118,7 +118,7 @@ pub fn build(b: *std.build.Builder) void { 这将始终在当前机器的调试模式下编译,因此对于初学者来说,这可能就足够了。但如果你想开始发布你的项目,你可能需要启用交叉编译: -# [交叉编译]($section.id('交叉编译')) +# [交叉编译]($section.id('cross-compilation')) 交叉编译是通过设置程序的目标和编译模式来实现的 @@ -187,7 +187,7 @@ zig build -Doptimize=ReleaseSmall 但我们仍然必须调用 zig build 编译,因为默认调用仍然没有任何作用。让我们改变一下! -# [安装工件]($section.id('安装工件')) +# [安装工件]($section.id('installing-artifacts')) 要安装任何东西,我们必须让它依赖于构建器的安装步骤。该步骤是已创建的,可通过 Builder.getInstallStep() 访问。我们还需要创建一个新的 InstallArtifactStep,将我们的 exe 文件复制到安装目录(通常是 zig-out) @@ -254,7 +254,7 @@ pub fn build(b: *std.build.Builder) void { 现在,从理解初始构建脚本到完全扩展,还缺少一个部分: -# [运行已构建的应用程序]($section.id('运行已构建的应用程序')) +# [运行已构建的应用程序]($section.id('running-built-application')) 为了开发用户体验和一般便利性,从构建脚本中直接运行程序是非常实用的。这通常是通过运行步骤实现的,可以通过 zig build run 调用。 diff --git a/content/post/2023-12-28-zig-build-explained-part2.smd b/content/post/2023-12-28-zig-build-explained-part2.smd index 44a44bd..e870030 100644 --- a/content/post/2023-12-28-zig-build-explained-part2.smd +++ b/content/post/2023-12-28-zig-build-explained-part2.smd @@ -9,15 +9,15 @@ > - 原文链接: https://zig.news/xq/zig-build-explained-part-2-1850 > - API 适配到 Zig 0.11.0 版本 -# [注释]($section.id('注释')) +# [注释]($section.id('notes')) 从现在起,我将只提供一个最精简的 build.zig,用来说明解决一个问题所需的步骤。如果你想了解如何将所有这些文件粘合到一个构建文件中,请阅读本系列[第一篇文章](2023-12-24-zig-build-explained-part1)。 -# [在命令行上编译 C 代码]($section.id('在命令行上编译 C 代码')) +# [在命令行上编译 C 代码]($section.id('compiling-c-code-on-command-line')) Zig 有两种编译 C 代码的方法,而且这两种很容易混淆。 -## [使用 zig cc]($section.id('使用 zig cc')) +## [使用 zig cc]($section.id('using-zig-cc')) Zig 提供了 LLVM c 编译器 clang。第一种是 zig cc 或 zig c++,它是与 clang 接近 1:1 的前端。由于我们无法直接从 build.zig 访问这些功能(而且我们也不需要!),所以我将在快速的介绍这个主题。 @@ -41,7 +41,7 @@ zig cc -o example.exe -target x86_64-windows-gnu buffer.c main.c 如你所见,只需向 -target 传递目标三元组,就能调用交叉编译。只需确保所有外部库都已准备好进行交叉编译即可! -# [使用 zig build-exe 和其他工具]($section.id('使用 zig build-exe 和其他工具')) +# [使用 zig build-exe 和其他工具]($section.id('using-zig-build-exe-and-other-tools')) 使用 Zig 工具链构建 C 项目的另一种方法与构建 Zig 项目的方法相同: @@ -59,7 +59,7 @@ zig build-exe -lc -target x86_64-windows-gnu main.c buffer.c 你会发现,使用这条编译命令,Zig 会自动在输出文件中附加 .exe 扩展名,并生成 .pdb 调试数据库。如果你在此处传递 --name example,输出文件也会有正确的 .exe 扩展名,所以你不必考虑这个问题。 -# [用 build.zig 创建 C 代码]($section.id('用 build.zig 创建 C 代码')) +# [用 build.zig 创建 C 代码]($section.id('creating-c-code-with-build-zig')) 那么,我们如何用 build.zig 来构建上面的两个示例呢? @@ -112,7 +112,7 @@ exe.addCSourceFile(.{ .file = std.build.LazyPath.relative("buffer.c"), .flags = exe.addCSourceFile(.{.file = std.build.LazyPath.relative("buffer.c"), .flags = &.{"-fno-sanitize=undefined"}}); ``` -# [使用外部库]($section.id('使用外部库')) +# [使用外部库]($section.id('using-external-libraries')) 通常情况下,C 项目依赖于其他库,这些库通常预装在 Unix 系统中,或通过软件包管理器提供。 @@ -181,7 +181,7 @@ zig build ./zig-out/bin/downloader https://mq32.de/public/ziggy.txt ``` -# [配置路径]($section.id('配置路径')) +# [配置路径]($section.id('configuring-paths')) 由于我们不能在交叉编译项目中使用 pkg-config,或者我们想使用预编译的专用库(如 BASS 音频库),因此我们需要配置包含路径和库路径。 @@ -220,7 +220,7 @@ pub fn build(b: *std.Build) void { addIncludePath 和 addLibraryPath 都可以被多次调用,以向编译器添加多个路径。这些函数不仅会影响 C 代码,还会影响 Zig 代码,因此 @cImport 可以访问包含路径中的所有头文件。 -# [每个文件的包含路径]($section.id('每个文件的包含路径')) +# [每个文件的包含路径]($section.id('include-paths-per-file')) 因此,如果我们需要为每个 C 文件设置不同的包含路径,我们就需要用不同的方法来解决这个问题: 由于我们仍然可以通过 addCSourceFile 传递任何 C 编译器标志,因此我们也可以在这里手动设置包含目录。 @@ -252,7 +252,7 @@ pub fn build(b: *std.Build) void { 上面的示例非常简单,所以你可能会想为什么需要这样的东西。答案是,有些库的头文件名称非常通用,如 api.h 或 buffer.h,而您希望使用两个共享头文件名称的不同库。 -# [构建 C++ 项目]($section.id('构建 C++ 项目')) +# [构建 C++ 项目]($section.id('building-cpp-projects')) 到目前为止,我们只介绍了 C 文件,但构建 C++ 项目并不难。你仍然可以使用 addCSourceFile,但只需传递一个具有典型 C++ 文件扩展名的文件,如 cpp、cxx、c++ 或 cc: @@ -285,7 +285,7 @@ pub fn build(b: *std.Build) void { 这就是构建 C++ 文件所需的全部知识,没有什么更神奇的了。 -# [指定语言版本]($section.id('指定语言版本')) +# [指定语言版本]($section.id('specifying-language-versions')) 试想一下,如果你创建了一个庞大的项目,其中的 C 或 C++ 文件有新有旧,而且可能是用不同的语言标准编写的。为此,我们可以使用编译器标志来传递 -std=c90 或 -std=c++98: @@ -320,7 +320,7 @@ pub fn build(b: *std.Build) void { } ``` -# [条件编译]($section.id('条件编译')) +# [条件编译]($section.id('conditional-compilation')) 与 Zig 相比,C 和 C++ 的条件编译方式非常繁琐。由于缺乏惰性求值的功能,有时必须根据目标环境来包含/排除文件。你还必须提供宏定义来启用/禁用某些项目功能。 @@ -373,7 +373,7 @@ pub fn build(b: *std.Build) void { 有条件地包含文件就像使用 if 一样简单,你可以这样做。只要不根据你想在构建脚本中定义的任何约束条件调用 addCSourceFile 即可。只包含特定平台的文件?看看上面的脚本就知道了。根据系统时间包含文件?也许这不是个好主意,但还是有可能的! -# [编译大型项目]($section.id('编译大型项目')) +# [编译大型项目]($section.id('compiling-large-projects')) 由于大多数 C(更糟糕的是 C++)项目都有大量文件(SDL2 有 411 个 C 文件和 40 个 C++ 文件),我们必须找到一种更简单的方法来编译它们。调用 addCSourceFile 400 次并不能很好地扩展。 @@ -478,7 +478,7 @@ pub fn build(b: *std.build.Builder) !void { 注意:其他构建系统会考虑文件名,而 Zig 系统不会!例如,在一个 qmake 项目中不能有两个名为 data.c 的文件!Zig 并不在乎,你可以添加任意多的同名文件,只要确保它们在不同的文件夹中就可以了 😏。 -# [编译 Objective C]($section.id('编译 Objective C')) +# [编译 Objective C]($section.id('compiling-objective-c')) 我完全忘了!Zig 不仅支持编译 C 和 C++,还支持通过 clang 编译 Objective C! @@ -514,7 +514,7 @@ pub fn build(b: *std.Build) void { 在这里,链接 libc 是隐式的,因为添加框架会自动强制链接 libc。是不是很酷? -# [混合使用 C 和 Zig 源代码]($section.id('混合使用 C 和 Zig 源代码')) +# [混合使用 C 和 Zig 源代码]($section.id('mixing-c-and-zig-source-code')) 现在,是最后一章: 混合 C 代码和 Zig 代码! diff --git a/content/post/2023-12-29-zig-build-explained-part3.smd b/content/post/2023-12-29-zig-build-explained-part3.smd index e7a962e..7da598f 100644 --- a/content/post/2023-12-29-zig-build-explained-part3.smd +++ b/content/post/2023-12-29-zig-build-explained-part3.smd @@ -11,17 +11,17 @@ 从现在起,我将只提供一个最精简的 build.zig,用来说明解决一个问题所需的步骤。如果你想了解如何将所有这些文件粘合到一个构建文件中,请阅读本系列[第一篇文章](2023-12-24-zig-build-explained-part1)。 -# [复合项目]($section.id('复合项目')) +# [复合项目]($section.id('composite-projects')) 有很多简单的项目只包含一个可执行文件。但是,一旦开始编写库,就必须对其进行测试,通常会编写一个或多个示例应用程序。当人们开始使用外部软件包、C 语言库、生成代码等时,复杂性也会随之上升。 本文试图涵盖所有这些用例,并将解释如何使用 build.zig 来编写多个程序和库。 -# [软件包]($section.id('软件包')) +# [软件包]($section.id('packages')) 译者:此处代码和说明,需要 zig build-exe --pkg-begin,但是在 0.11 已经失效。所以删除。 -# [库]($section.id('库')) +# [库]($section.id('libraries')) 但 Zig 也知道库这个词。但我们不是已经讨论过外部库了吗? @@ -36,7 +36,7 @@ 在 Zig 中,我们需要导入库的头文件,如果头文件在 Zig 中,则使用包,如果是 C 语言头文件,则使用 @cImport。 -# [工具]($section.id('工具')) +# [工具]($section.id('tools')) 如果我们的项目越来越多,那么在构建过程中就需要使用工具。这些工具通常会完成以下任务: @@ -48,7 +48,7 @@ 但我们如何在 build.zig 中完成这些工作呢? -# [添加软件包]($section.id('添加软件包')) +# [添加软件包]($section.id('adding-packages')) 添加软件包通常使用 LibExeObjStep 上的 addPackage 函数。该函数使用一个 std.build.Pkg 结构来描述软件包的外观: @@ -98,7 +98,7 @@ exe.addModule("lola",pkgs.lola); exe.addModule("args",pkgs.args); ``` -# [添加库]($section.id('添加库')) +# [添加库]($section.id('adding-libraries')) 添加库相对容易,但我们需要配置更多的路径。 @@ -106,7 +106,7 @@ exe.addModule("args",pkgs.args); 假设我们要将 libcurl 链接到我们的项目,因为我们要下载一些文件。 -## [系统库]($section.id('系统库')) +## [系统库]($section.id('system-libraries')) 对于 unixoid 系统,我们通常可以使用系统软件包管理器来链接系统库。方法是调用 linkSystemLibrary,它会使用 pkg-config 自行找出所有路径: @@ -137,7 +137,7 @@ pub fn build(b: *std.Build) void { 对于 Linux 系统,这是链接外部库的首选方式。 -## [本地库]($section.id('本地库')) +## [本地库]($section.id('local-libraries')) 不过,您也可以链接您作为二进制文件提供商的库。为此,我们需要调用几个函数。首先,让我们来看看这样一个库是什么样子的: @@ -167,7 +167,7 @@ include 我们可以看到,vendor/libcurl/include 路径包含我们的头文件,vendor/libcurl/lib 文件夹包含一个静态库(libcurl.a)和一个共享/动态库(libcurl.so)。 -## [动态链接]($section.id('动态链接')) +## [动态链接]($section.id('dynamic-linking')) 要链接 libcurl,我们需要先添加 include 路径,然后向 zig 提供库的前缀和库名:(todo 代码有待验证,因为 curl 可能需要自己编译自己生成 static lib) @@ -197,7 +197,7 @@ addLibraryPath 对库文件也有同样的作用。这意味着 Zig 现在也会 最后,linkSystemLibrary 会告诉 Zig 搜索名为 "curl "的库。如果你留心观察,就会发现上面列表中的文件名是 libcurl.so,而不是 curl.so。在 unixoid 系统中,库文件的前缀通常是 lib,这样就不会将其传递给系统。在 Windows 系统中,库文件的名字应该是 curl.lib 或类似的名字。 -# [静态链接]($section.id('静态链接')) +# [静态链接]($section.id('static-linking')) 当我们要静态链接一个库时,我们必须采取一些不同的方法: @@ -250,7 +250,7 @@ pub fn build(b: *std.build.Builder) void { 我们可以继续静态链接越来越多的库,并拉入完整的依赖关系树。 -# [通过源代码链接库]($section.id('通过源代码链接库')) +# [通过源代码链接库]($section.id('linking-libraries-from-source')) 不过,我们还有一种与 Zig 工具链截然不同的链接库方式: @@ -293,7 +293,7 @@ pub fn build(b: *std.build.Builder) void { 这一点尤其方便,因为我们可以使用 setTarget 和 setBuildMode 从任何地方编译到任何地方。 -# [使用工具]($section.id('使用工具')) +# [使用工具]($section.id('using-tools')) 在工作流程中使用工具,通常是在需要以 bison、flex、protobuf 或其他形式进行预编译时。工具的其他用例包括将输出文件转换为不同格式(如固件映像)或捆绑最终应用程序。 @@ -352,7 +352,7 @@ size 是一个很好的工具,它可以输出有关可执行文件代码大小 如您所见,我们在这里使用了 addArtifactArg,因为 addSystemCommand 只会返回一个 std.build.RunStep。这样,我们就可以增量构建完整的命令行,包括任何 LibExeObjStep 输出、FileSource 或逐字参数。 -# [全新工具]($section.id('全新工具')) +# [全新工具]($section.id('new-tools')) 最酷的是 我们还可以从 LibExeObjStep 获取 std.build.RunStep: @@ -389,7 +389,7 @@ pub fn build(b: *std.build.Builder) void { 调用 zig build pack 时,我们将运行 tools/pack.zig。这很酷,因为我们还可以从头开始编译所需的工具。为了获得最佳的开发体验,你甚至可以从源代码编译像 bison 这样的 "外部 "工具,这样就不会依赖系统了! -# [将所有内容放在一起]($section.id('将所有内容放在一起')) +# [将所有内容放在一起]($section.id('putting-it-all-together')) 一开始,所有这些都会让人望而生畏,但如果我们看一个更大的 build.zig 实例,就会发现一个好的构建文件结构会给我们带来很大帮助。 @@ -491,7 +491,7 @@ pub fn build(b: *std.build.Builder) void { 两者都是为了在主机平台上运行,而不是在目标机器上。 此外,deploy_tool 还设置了固定的编译模式,因为我们希望快速编译,即使我们编译的是应用程序的调试版本。 -# [总结]($section.id('summary')) +# [总结]($section.id('conclusion')) 看完这一大堆文字,你现在应该可以构建任何你想要的项目了。我们已经学会了如何编译 Zig 应用程序,如何为其添加任何类型的外部库,甚至如何为发布管理对应用程序进行后处理。 diff --git a/content/post/2024-01-12-how-to-release-your-zig-applications.smd b/content/post/2024-01-12-how-to-release-your-zig-applications.smd index 09e5d58..d768147 100644 --- a/content/post/2024-01-12-how-to-release-your-zig-applications.smd +++ b/content/post/2024-01-12-how-to-release-your-zig-applications.smd @@ -14,7 +14,7 @@ You've just written an application in Zig and want others to use it. A convenient way for users to use your application is to provide a pre-built executable file. Next, I'll discuss the two main things that need to be handled correctly in a good release process. -# [Why provide pre-built executable files?]($section.id('Why provide pre-built executable files?')) +# [Why provide pre-built executable files?]($section.id('why-provide-pre-built-executable-files')) Given how C/C++ dependencies work (or don't work), for some C/C++ projects, providing pre-compiled executable files is almost a necessity, @@ -26,7 +26,7 @@ That said, the more popular your application is, the less users will care what l Your users don't want to install Zig and run the build process to easily use your application (99% of the time, the rest 1% will be discussed later), so it's still better to pre-build your application. -# [`zig build` vs `zig build-exe`]($section.id('`zig build` vs `zig build-exe`')) +# [`zig build` vs `zig build-exe`]($section.id('zig-build-vs-zig-build-exe')) In this article, we'll see how to make, release a build for a Zig project, so it's worth spending a little time to fully understand the relationship between Zig build system and command line. @@ -48,7 +48,7 @@ what `zig build` does is to prepare command line parameters for `build-exe`. This means that in compiling Zig code, `zig build` (assuming the code in `build.zig` is correct) and `zig build-exe` are one-to-one correspondence. The only difference is convenience. -# [Build mode]($section.id('Build mode')) +# [Build mode]($section.id('build-mode')) When building a Zig project with `zig build` or `zig build-exe myapp.zig`, the default is a debug build executable file. Debug build is mainly for development convenience, so it's usually considered unsuitable for release. @@ -70,7 +70,7 @@ but it's not prioritized for performance, but rather for trying to minimize the For example, this is a very meaningful build mode for WebAssembly, because you want the executable file to be as small as possible, and the sandbox runtime environment has provided a lot of security guarantees. -# [How to set build mode]($section.id('How to set build mode')) +# [How to set build mode]($section.id('how-to-set-build-mode')) When using `zig build-exe`, you can add `-O ReleaseSafe` (or `ReleaseFast`, or `ReleaseSmall`) to get the corresponding build mode. @@ -98,7 +98,7 @@ const exe = b.addExecutable(.{ This is how you specify release mode in command line: `zig build -Doptimize=ReleaseSafe` (or `-Doptimize=ReleaseFast`, or `-Doptimize=ReleaseSmall`). -# [Choose the correct build target]($section.id('Choose the correct build target')) +# [Choose the correct build target]($section.id('choose-the-correct-build-target')) Now, we've chosen the correct release mode, it's time to consider build target. Obviously, if the platform used and build platform are different, the corresponding build target needs to be specified, @@ -109,7 +109,7 @@ The most straightforward way is to directly call `zig build` or `zig build-exe` If you do this, sometimes it works, but sometimes it crashes due to `illegal instruction` (or similar error). What's happening? -# [CPU features]($section.id('CPU features')) +# [CPU features]($section.id('cpu-features')) If build target is not specified when building, Zig will build for the current machine, which means it will use all instruction sets supported by the current CPU. If the CPU supports AVX extension, diff --git a/content/post/2024-04-06-zig-cpp.smd b/content/post/2024-04-06-zig-cpp.smd index 7a9afe3..11c3275 100644 --- a/content/post/2024-04-06-zig-cpp.smd +++ b/content/post/2024-04-06-zig-cpp.smd @@ -8,7 +8,7 @@ 尽管 Zig 社区宣称 Zig 语言是一个更好的 C (better C),但是我个人在学习 Zig 语言时经常会"触类旁通"C++。在这里列举一些例子来说明我的一些体会,可能会有一些不正确的地方,欢迎批评指正。 -# ["元能力" vs "元类型"]($section.id('"元能力" vs "元类型"')) +# ["元能力" vs "元类型"]($section.id('meta-ability-vs-meta-type')) 在我看来,C++的增强方式是希望赋予语言一种"元能力",能够让人重新发明新的类型,使得使用 C++的程序员使用自定义的类型,进行一种类似于"领域内语言"(DSL)编程。一个通常的说法就是 C++中任何类型定义都像是在模仿基本类型`int`。比如我们有一种类型 T,那么我们则需要定义 T 在以下几种使用场景的行为: @@ -26,7 +26,7 @@ x = y; //x的类型是T,复制运算符重载,当然也有可能是移动运 不过话说回来,很多底层系统的开发需求往往和这种类型系统的构建相悖,比如如果你的类型就是一个`int`的封装,那么即使发生拷贝你也无所谓性能开销。但是如果是一个`struct`,那么通常情况下,你会比较 care 拷贝,而可能考虑"移动"之类的手段。这个时候各种 C++的提供的幻觉,就成了程序员开发的绊脚石,经常你需要分析一段 C++表达式里到底有没有发生拷贝,他是左值还是右值,其实你在写 C 语言的时候也很少去考虑了这些,你在 Zig 里同样也不需要。 -# [类型系统]($section.id('类型系统')) +# [类型系统]($section.id('type-system')) C 语言最大弊病就是没有提供标准库,C++的标准库你要是能看懂,得具备相当的 C++的语法知识,但是 Zig 的标准库几乎不需要文档就能看懂。这其实是因为,在 C++里,类型不是一等成员(first class member),因此实现一些模版元编程算法特别不直观。但是在 Zig 里,`type`就是一等成员,比如你可以写: @@ -63,7 +63,7 @@ Some::OutputType 相当于对于 InputType 调用一个 Some"函数",然后输出一个 OutputType。 -# [命令式 VS 声明式]($section.id('命令式 VS 声明式')) +# [命令式 VS 声明式]($section.id('command-vs-declaration')) 比如实现一个函数,输入一个 bool 值,根据 bool 值,如果为真,那么输出 type A,如果为假那么输出 type B。 diff --git a/content/post/2024-05-07-package-hash.smd b/content/post/2024-05-07-package-hash.smd index 0267ce5..630cf9f 100644 --- a/content/post/2024-05-07-package-hash.smd +++ b/content/post/2024-05-07-package-hash.smd @@ -10,7 +10,7 @@ > 原文地址:[build.zig.zon dependency hashes](https://zig.news/michalsieron/buildzigzon-dependency-hashes-47kj) -# [引言]($section.id('引言')) +# [引言]($section.id('introduction')) 作者 Michał Sieroń 最近在思考 `build.zig.zon` 中的依赖项哈希值的问题。这些哈希值都有相同的前缀,而这对加密哈希函数来说极其不同寻常。习惯性使用 Conda 和 Yocto 对下载的压缩包运行 sha256sum,但生成的摘要与 `build.zig.zon` 中的哈希值完全不同。 @@ -34,7 +34,7 @@ 以上摘取自 [hexops/mach](https://github.com/hexops/mach/blob/bffc66800584123e2844c4bc4b577940806f9088/build.zig.zon#L13-L26) 项目。 -# [初步探索]($section.id('初步探索')) +# [初步探索]($section.id('initial-investigation')) 经过一番探索,我找到了一个文档:[doc/build.zig.zon.md](https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/doc/build.zig.zon.md),似乎没有任何线索指向它。而文档中对哈希有段简短的描述。 @@ -44,7 +44,7 @@ 该哈希值是基于一系列文件内容计算得出的,这些文件是在获取URL后并应用了路径规则后得到的。 这个字段是最重要的;一个包是的唯一性是由它的哈希值确定的,不同的 URL 可能对应同一个包。 -# [多重哈希]($section.id('多重哈希')) +# [多重哈希]($section.id('multihash')) 在他们的网站上有一个很好的可视化展示,说明了这一过程: [多重哈希](https://multiformats.io/multihash/)。 @@ -52,7 +52,7 @@ 因此 `build.zig.zon` 中的哈希字段不仅包含了摘要(digest),还包含了一些元数据(metadata)。但即使我们丢弃了头部信息,得到的结果仍与下载的 `tar` 包的 `sha256` 摘要不相符。而这就涉及到了包含规则的问题。 -# [包含规则(inclusion rules)]($section.id('包含规则(inclusion rules)')) +# [包含规则(inclusion rules)]($section.id('inclusion-rules')) 回到 [doc/build.zig.zon.md](https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/doc/build.zig.zon.md) 文件,我们看到: @@ -93,7 +93,7 @@ pub fn includePath(self: Filter, sub_path: []const u8) bool { 除此之外,这个函数会检查 `sub_path` 是否被明确列出,或者是已明确列出的目录的子目录。 -# [计算哈希]($section.id('计算哈希')) +# [计算哈希]($section.id('compute-hash')) 现在我们知道了 `build.zig.zon` 的包含规则,也知道使用了 `SHA256` 算法。但我们仍然不知道实际的哈希结果是如何得到的。例如,它可能是通过将所有包含的文件内容输入哈希器来计算的。所以让我们再仔细看看,也许我们可以找到答案。 @@ -121,7 +121,7 @@ try all_files.append(hashed_file); 跟踪 `workerHashFile`,我们看到它是 `hashFileFallible` 的一个简单包装,而后者看起来相当复杂。让我们来分解一下。 -# [单个文件的哈希计算]($section.id('单个文件的哈希计算')) +# [单个文件的哈希计算]($section.id('single-file-hash')) 首先,会进行一些初始化设置,其中创建并用规整后的文件路径初始化了一个新的哈希器实例: @@ -169,7 +169,7 @@ hasher.update(link_name); 首先进行路径分隔符的规整,保证不同平台一致,之后将符号链接的目标路径输入 `hasher`。在 `hashFileFallible` 函数最后,把计算出的哈希值赋值给 `HashedFile` 对象的 `hash` 字段。 -# [组合哈希]($section.id('组合哈希')) +# [组合哈希]($section.id('combining-hashes')) 尽管有了单个文件的哈希值,但我们仍不知道如何得到最终的哈希。幸运的是,曙光就在眼前。 @@ -199,13 +199,13 @@ for (all_files.items) |hashed_file| { 在这里我们看到所有计算出的哈希被一个接一个地输入到一个新的哈希器中。在 `computeHash` 的最后,我们返回 `hasher.finalResult()`,现在我们明白哈希值是如何获得的了。 -# [最终多哈希值]($section.id('最终多哈希值')) +# [最终多哈希值]($section.id('final-multi-hash')) 现在我们有了一个 `SHA256` 摘要,可以最终返回到 `main.zig`,在那里我们调用 [`Package.Manifest.hexDigest(fetch.actual_hash)`](https://github.com/ziglang/zig/blob/9d64332a5959b4955fe1a1eac793b48932b4a8a8/src/Package/Manifest.zig#L174)。在那里,我们将多哈希头写入缓冲区,之后是我们的组合摘要。 顺便说一下,我们看到所有哈希头都是 `1220` 并非巧合。这是因为 `Zig` [硬编码了 SHA256](https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/src/Package/Manifest.zig#L3) - 0x12,它有 32 字节的摘要 - 0x20。 -# [总结]($section.id('总结')) +# [总结]($section.id('summary')) 总结一下:最终哈希值是一个多哈希头 + `SHA256` 摘要。 diff --git a/content/post/2024-05-24-interface-idioms.smd b/content/post/2024-05-24-interface-idioms.smd index 916fd21..1b31009 100644 --- a/content/post/2024-05-24-interface-idioms.smd +++ b/content/post/2024-05-24-interface-idioms.smd @@ -8,7 +8,7 @@ > 原文链接: https://zig.news/yglcode/code-study-interface-idiomspatterns-in-zig-standard-libraries-4lkj -# [引言]($section.id('引言')) +# [引言]($section.id('introduction')) 在 Java 和 Go 中,可以使用“接口”(一组方法或方法集)定义基于行为的抽象。通常接口包含所谓的虚表(`vtable`) 以实现动态分派。Zig 允许在结构体、枚举、联合和不透明类型中声明函数和方法,尽管 Zig 尚未支持接口作为一种语言特性。 @@ -31,7 +31,7 @@ Zig 标准库应用了一些代码习语或模式以达到类似效果。 完整代码位于[此仓库](https://github.com/yglcode/zig_interfaces),你可以使用 `zig test interfaces.zig` 运行它。 -# [背景设定]($section.id('背景设定')) +# [背景设定]($section.id('background')) 让我们使用经典的面向对象编程示例,创建一些形状:点(`Point`)、盒子(`Box`)和圆(`Circle`)。 @@ -86,7 +86,7 @@ fn init_data() struct { point: Point, box: Box, circle: Circle } { } ``` -# [接口1:枚举标签联合]($section.id('接口1:枚举标签联合')) +# [接口1:枚举标签联合]($section.id('enum-tagged-union')) Loris Cro 在[“使用 Zig 0.10.0 轻松实现接口”](https://zig.news/kristoff/easy-interfaces-with-zig-0100-2hc5) 中介绍了使用枚举标签联合作为接口的方法。这是最简单的解决方案,尽管你必须在联合类型中显式列出所有“实现”该接口的变体类型。 @@ -126,7 +126,7 @@ test "union_as_intf" { } ``` -# [接口2:vtable 和动态分派的第一种实现]($section.id('接口2:vtable 和动态分派的第一种实现')) +# [接口2:vtable 和动态分派的第一种实现]($section.id('vtable-and-dynamic-dispatch')) Zig 已从最初基于嵌入式 `vtab` 和 `#fieldParentPtr()` 的动态分派切换到基于“胖指针”接口的以下模式; 请查阅此文章了解更多细节[“Allocgate 将在 Zig 0.9 中到来...”](https://pithlessly.github.io/allocgate.html)。 @@ -198,7 +198,7 @@ test "vtab1_as_intf" { } ``` -# [接口3:vtable 和动态分派的第二种实现]($section.id('接口3:vtable 和动态分派的第二种实现')) +# [接口3:vtable 和动态分派的第二种实现]($section.id('vtable-and-dynamic-dispatch')) 在上述第一种实现中,通过 `Shape2.init()` 将 `Box` “转换”为接口 `Shape2` 时,会对 `box` 实例进行类型检查, 以确保其实现了 `Shape2` 的方法(包括名称的匹配签名)。第二种实现中有两个变化: @@ -271,7 +271,7 @@ test "vtab2_as_intf" { } ``` -# [接口4:使用嵌入式 vtab 和 @fieldParentPtr() 的原始动态分派]($section.id('接口4:使用嵌入式 vtab 和 @fieldParentPtr() 的原始动态分派')) +# [接口4:使用嵌入式 vtab 和 @fieldParentPtr() 的原始动态分派]($section.id('vtab-and-fieldparentptr')) 接口 `std.build.Step` 和所有构建步骤 `std.build.[RunStep, FmtStep, ...]` 仍然使用这种模式。 @@ -364,7 +364,7 @@ test "vtab3_embedded_in_struct" { } ``` -# [接口5:编译时的泛型接口]($section.id('interface-5-compile-time-generic-interface')) +# [接口5:编译时的泛型接口]($section.id('compile-time-generic-interface')) 所有上述接口都侧重于 `vtab` 和动态分派:接口值将隐藏其持有的具体值的类型。因此,你可以将这些接口值放入数组中并统一处理。 diff --git a/content/post/2024-06-10-zig-hashmap-1.smd b/content/post/2024-06-10-zig-hashmap-1.smd index ba84b9f..986109d 100644 --- a/content/post/2024-06-10-zig-hashmap-1.smd +++ b/content/post/2024-06-10-zig-hashmap-1.smd @@ -24,7 +24,7 @@ pub fn put(self: *Self, key: K, value: V) Allocator.Error!void { 正如我所说,大部分繁重的工作都由 `std.HashMapUnmanaged` 完成,其他变体通过一个名为 `unmanaged` 的字段对其进行封装。 -# [Unmanaged]($section.id('Unmanaged')) +# [Unmanaged]($section.id('unmanaged')) 在Zig标准库中随处可见的类型命名约定是 `unmanaged`。这种命名方式表明所涉及的类型不维护 `allocator`。任何需要分配内存的方法都会显式地将 `allocator` 作为参数传递。要实际看到这一点,可以考虑下面这个链表的例子: @@ -143,7 +143,7 @@ pub fn LinkedList(comptime T: type) type { 为了简化,本文的其余部分不会再提到 `unmanaged`。我们看到关于 `StringHashMap` 或 `AutoHashMap` 或 `HashMap` 的任何内容同样适用于它们的 Unmanaged 变体。 -# [HashMap 与 AutoHashMap]($section.id('HashMap 与 AutoHashMap')) +# [HashMap 与 AutoHashMap]($section.id('hashmap-and-autohashmap')) std.HashMap 是一个泛型类型,它接受两个类型参数:键的类型和值的类型。正如我们所见,哈希映射需要两个函数:hash 和 eql。这两个函数合起来被称为“上下文(context)”。这两个函数都作用于键,并且没有一个单一的 hash 或 eql 函数适用于所有类型。例如,对于整数键,eql 将是 `a_key == b_key`;而对于 `[]const u8` 键,我们希望使用 `std.mem.eql(u8, a_key, b_key)`。 @@ -234,7 +234,7 @@ pub const StringContext = struct { }; ``` -# [自定义上下文]($section.id('自定义上下文')) +# [自定义上下文]($section.id('context-customization')) 我们将在第一部分结束时,直接使用 `HashMap`,这意味着提供我们自己的上下文。我们将从一个简单的例子开始:为不区分大小写的 ASCII 字符串创建一个 `HashMap`。我们希望以下内容输出:`Goku = 9000`。请注意,虽然我们使用键 `GOKU` 进行插入,但我们使用“goku”进行获取: diff --git a/content/post/2024-06-11-zig-hashmap-2.smd b/content/post/2024-06-11-zig-hashmap-2.smd index dac855e..1091908 100644 --- a/content/post/2024-06-11-zig-hashmap-2.smd +++ b/content/post/2024-06-11-zig-hashmap-2.smd @@ -41,7 +41,7 @@ keys: values: 这个基本的可视化表示将贯穿本文大部分内容,并且不断强调条目的位置需要保持一致性和可预测性。即使哈希表需要在增长时从一个底层数组移动到另一个(即当填充因子达到一定阈值并要求扩大以容纳更多数据时),这一事实是我们将反复回顾的主题。 -# [值管理]($section.id('值管理')) +# [值管理]($section.id('values-management')) 如果我们对上述代码片段进行扩展,并调用 `lookup.get("Paul")`,返回的值将是 `1234`。在处理像 `i32` 这样的原始类型时,很难直观地理解 `get` 方法和它的可选返回类型 `?i32` 或更通用的 `?V`(其中 `V` 表示任何值类型)之间的区别。考虑到这一点,让我们通过替换 `i32` 为一个封装了更多信息的 `User` 类型来展示这一概念: @@ -224,7 +224,7 @@ while (it.next()) |value_ptr| { 在最后一种情况下,由于我们存储的是 `User` 而不是 `*User`,我们的 `value_ptr` 是指向 `User` 的指针(不像之前那样是指向指针的指针)。 -# [Keys]($section.id('Keys')) +# [Keys]($section.id('keys')) 我们可以开始和结束这一节:我们关于值的所有内容同样适用于键。这是100%正确的,但这在某种程度上不太直观。大多数开发人员很快就能理解,存储在哈希表中的堆分配的 `User` 实例有其自身的生命周期,需要显式管理/释放。但由于某些原因,这对于键来说并不那么明显。 @@ -337,7 +337,7 @@ if (lookup.fetchRemove(user.name)) |kv| { 对于大多数情况,在处理非原始键或值时,关键是当你调用哈希表的 `deinit` 时,你为键和值分配的任何内存不会被自动释放;你需要自己处理。 -# [getOrPut]($section.id('getOrPut')) +# [getOrPut]($section.id('getorput')) 虽然我们已经讨论过的内容有很多含义,但对我来说,直接暴露键和值指针的最大好处之一是 `getOrPut` 方法。 diff --git a/content/post/2024-08-12-zoop.smd b/content/post/2024-08-12-zoop.smd index fe939ce..0a63100 100644 --- a/content/post/2024-08-12-zoop.smd +++ b/content/post/2024-08-12-zoop.smd @@ -14,9 +14,9 @@ zoop 是 zig 的一个 OOP 解决方案,详细信息可以看看 [zoop官网]( 简单的说,是我个人原因,必需使用 zig 的同时,还一定要用 OOP,所以有了 zoop。 -# [zoop 入门]($section.id('zoop 入门')) +# [zoop 入门]($section.id('intro-to-zoop')) -# [类和方法]($section.id('类和方法')) +# [类和方法]($section.id('class-and-method')) ```zig pub const Base = struct { @@ -73,7 +73,7 @@ pub const Base = struct { 上面的代码给 `Base` 添加了一个可以继承的方法 `getName()`。 -# [类的继承]($section.id('类的继承')) +# [类的继承]($section.id('class-inheritance')) zoop 引入一个关键字 `extends` 用来实现继承,比如下面我们定义 `Base` 的子类 `Child`: @@ -102,7 +102,7 @@ test { } ``` -# [接口定义]($section.id('接口定义')) +# [接口定义]($section.id('interface-define')) zoop 中的接口,实际上是一个胖指针。下面我们定义一个接口 `IGetName`: @@ -132,7 +132,7 @@ pub const IGetName = struct { 上面的代码具体原理下面会说到,这里大家知道接口就是这样定义的就行了。上面的代码定义了接口 `IGetName`,这个接口有一个方法 `getName()`。 -# [接口实现]($section.id('接口实现')) +# [接口实现]($section.id('interface-implementation')) 上面的 `Base` 类正好也有个符合 `IGetName` 接口的方法 `getName()`,那我们修改一下 `Base` 的代码让它来实现 `IGetName` 接口: @@ -148,7 +148,7 @@ pub const Base = struct { 可以看到实现接口和继承用的同样一个关键字 `extends`。因为子类会继承父类的接口,所以这样一来,`Child` 也自动实现了 `IGetName` 接口。 -# [方法重写和虚函数调用]($section.id('方法重写和虚函数调用')) +# [方法重写和虚函数调用]($section.id('method-override-and-virtual-call')) 我们修改上面 `Child` 的代码,重写 `getName()` 方法: @@ -194,7 +194,7 @@ try t.expectEqualStrings(base.as(IGetName).?.getName(), "override"); 那么 zoop 的基本使用方法就介绍到这里,下面我们开始介绍 zoop 的实现原理。 -# [预设场景]($section.id('预设场景')) +# [预设场景]($section.id('preset-scene')) 接下来的讨论基于如下的属于 `mymod` 模块的类和接口: @@ -285,7 +285,7 @@ pub const Child = struct { - `Base`: 基类,实现接口 `ISetName` - `Child`: 子类,继承 `Base`,并实现接口 `IGetName` -# [核心数据结构 `zoop.Mixin(T)`]($section.id('核心数据结构 `zoop.Mixin(T)`')) +# [核心数据结构 `zoop.Mixin(T)`]($section.id('core-data-structure')) 我们看看两个类的 `mixin` 这个数据里面有什么: @@ -339,7 +339,7 @@ zoop.Mixin(Child) = struct { 上面两个函数获取的都是最外层对象的数据。根据对 `mixin` 数据的分析,zoop 的类型转换的原理就很清楚了,大家可以参考官网上关于 [类型转换](https://zhuyadong.github.io/zoop-docs/guide/as-cast) 的内容。 -# [动态构造类的方法、接口方法、和 `Vtable`]($section.id('动态构造类的方法、接口方法、和 `Vtable`')) +# [动态构造类的方法、接口方法、和 `Vtable`]($section.id('dynamic-construct-class-method-interface-method-and-vtable')) OOP 概念中的继承,重写,虚函数,实质其实就是在编译时动态构造需要的方法和属性。zoop 中主要是通过通过 [zoop.tuple](https://zhuyadong.github.io/zoop-docs/reference/tuple) 这个模块来进行编译时动态构造。 @@ -347,11 +347,11 @@ OOP 概念中的继承,重写,虚函数,实质其实就是在编译时动 下面我介绍一下 zoop 中用到的 `comptime` 一些技巧,相信会对大家今后使用 zig 有帮助。 -# [`struct` 很万能]($section.id('`struct` 很万能')) +# [`struct` 很万能]($section.id('struct-very-good')) `comptime` 编程中,`struct` 是你最好的朋友,想在不同的 `comptime` 函数之间传递数据,最方便的方式,就是通过构造一个 `struct`,把想传递的数据通过 `pub const xxx = ...` 的方式传递出去,通过 `struct` 保存数据最好的地方,就在于这个数据在运行时也是可用的 (`struct` 中的常量,是保存在 exe 的 `.data` 区,运行时可见),[zoop.tuple](https://zhuyadong.github.io/zoop-docs/reference/tuple) 就是通过这个方法实现的。 -# [动态构造 `struct` 的字段,用 `@Type()`]($section.id('动态构造 `struct` 的字段,用 `@Type()`')) +# [动态构造 `struct` 的字段,用 `@Type()`]($section.id('dynamic-construct-struct-field-use-type')) 网上好像很少有关于 `@Type()` 的使用说明,一般都是通过看 `zig.std` 的代码来学习,那我这里就稍微说明一下,希望能对大家有帮助。 目前 zig 通过 `@Type()`,能动态构造的 `struct`,只有纯字段类型的 `struct` (个人理解)。构造的方法,就是先把计算好的一个 `std.builtin.Type.StructField` 数组传递给 `@Type()` 来返回一个 `struct`,比如以下代码: @@ -398,7 +398,7 @@ const MyStruct = struct { zoop 动态构造 `Vtable` 就是通过这个方法做到的,参考 [zoop.DefVtable 原理](https://zhuyadong.github.io/zoop-docs/reference/principle#DefVtable) 和 [zoop 源代码](https://github.com/zhuyadong/zoop.git) -# [动态构造 `struct` 的函数,用 `usingnamespace`]($section.id('动态构造 `struct` 的函数,用 `usingnamespace`')) +# [动态构造 `struct` 的函数,用 `usingnamespace`]($section.id('dynamic-construct-struct-function-use-usingnamespace')) 要想定义 `struct` 中的函数,理论上代码是一定要写在 `struct` 中的,目前 zig 唯一留下的一个口子,就是 `usingnamespace`,zoop 正是利用这个特性,来动态构造 `struct` 的函数。 diff --git a/content/post/2024-11-26-typed-fsm.smd b/content/post/2024-11-26-typed-fsm.smd index 8ae6d63..22ba1d3 100644 --- a/content/post/2024-11-26-typed-fsm.smd +++ b/content/post/2024-11-26-typed-fsm.smd @@ -548,7 +548,7 @@ pub fn readyHandler(comptime w: AtmSt.EWitness(.ready), ist: *InternalState) voi 遵循这四点要求,就能获得强大的类型安全保证,足以让你愉快的使用状态机! -# [5. 接下来能够增强的功能]($section.id('5-future-enhancements')) +# [5. 接下来能够增强的功能]($section.id('future-enhancements')) 暂时我能想到的有如下几点: diff --git a/content/post/2025-01-23-bonkers-comptime.smd b/content/post/2025-01-23-bonkers-comptime.smd index 24658b3..f800ed2 100644 --- a/content/post/2025-01-23-bonkers-comptime.smd +++ b/content/post/2025-01-23-bonkers-comptime.smd @@ -178,7 +178,7 @@ pub fn main() !void { comptime 和运行时之间有一些小的区别。比如,只有 comptime 可以访问类型为 comptime_int、comptime_float 或 type 的变量。此外,一些函数只有 comptime 参数,这使它们仅限于编译时环境。相对的,只有运行时才能进行系统调用和那些依赖系统调用的函数。如果你的代码不使用这些特性,那么它在编译时和运行时中的表现将是一样的。 -# [视角3:[程序特化](https://en.wikipedia.org/wiki/Partial_application) +# [视角3:[程序特化]($section.id('perspective-3-partial-evaluation')) > 译者注:程序特化(Partial Evaluation)是一种编译优化技术,主要是:在编译期预先计算部分表达式或代码路径,以减少运行时计算开销,提前生成更具体的代码实现。 diff --git a/content/post/2025-07-19-zine-migration.smd b/content/post/2025-07-19-zine-migration.smd index 6f44305..b8afdf1 100644 --- a/content/post/2025-07-19-zine-migration.smd +++ b/content/post/2025-07-19-zine-migration.smd @@ -205,7 +205,7 @@ Zine 官方文档提供了详细的部署指南: 你可以参考 zine-ssg 或本站(ZigCC)仓库中的 GitHub Actions 配置来设置自己的自动化部署流程。 -# [四、总结与经验分享]($section.id("总结与经验分享")) +# [四、总结与经验分享]($section.id('summary-and-experience-sharing')) 最后,分享几点额外的经验: diff --git a/content/post/index.smd b/content/post/index.smd index ed228fc..13ee7e7 100644 --- a/content/post/index.smd +++ b/content/post/index.smd @@ -8,4 +8,4 @@ 欢迎大家向我们投稿,会同步到微信公众号,投稿方式见[这里](./2023-09-05-hello-world)。 -[社区新闻](./news) \ No newline at end of file +[社区新闻]($section.id('community-news')) \ No newline at end of file diff --git a/content/post/news/2023-12-11-first-meetup.smd b/content/post/news/2023-12-11-first-meetup.smd index ad8f810..fd6c961 100644 --- a/content/post/news/2023-12-11-first-meetup.smd +++ b/content/post/news/2023-12-11-first-meetup.smd @@ -12,7 +12,7 @@ [会议参会人员]($image.siteAsset('images/first-online-meeting.webp')) -和当年的从仙童半导体出逃的人数一样,不多不少。😄 [硅谷八叛徒]($image.siteAsset('images/fair-children.webp')) +和当年的从仙童半导体出逃的人数一样,不多不少。😄 [硅谷八叛徒]($section.id('traitorous-eight')) 会议伊始,成员首先进行了个人简介,便于后续开展相应工作。随后,社区成员围绕 Zig 语言的普及进行了交流讨论。 diff --git a/content/post/news/2023-12-27-second-meetup.smd b/content/post/news/2023-12-27-second-meetup.smd index ddcce3e..db81432 100644 --- a/content/post/news/2023-12-27-second-meetup.smd +++ b/content/post/news/2023-12-27-second-meetup.smd @@ -18,7 +18,7 @@ 这次会议主要是同步了之前会议落实的 action,主要是同步了不同项目的进展,由于临近年底,大家进度都不算太大,但还是有所进展,算是开了个好头😄 -# [项目进展]($section.id('项目进展')) +# [项目进展]($section.id('project-progress')) # [Zig-OS](https://github.com/zigcc/zig-os) diff --git a/content/post/news/2024-01-14-third-meetup.smd b/content/post/news/2024-01-14-third-meetup.smd index e7024d6..c3254aa 100644 --- a/content/post/news/2024-01-14-third-meetup.smd +++ b/content/post/news/2024-01-14-third-meetup.smd @@ -18,7 +18,7 @@ - 公众号运营 - 如何与其他社区互动 -# [公众号运营]($section.id('公众号运营')) +# [公众号运营]($section.id('public-account-operation')) 这是最近群里聊到的问题,由于 Zig 语言本身属于较新的技术,因此社区内资料比较少,这导致很多感兴趣的人没有一个好的学习途径。