Skip to content
This repository has been archived by the owner on Aug 24, 2024. It is now read-only.

Commit

Permalink
Translate code comments (#34)
Browse files Browse the repository at this point in the history
* Translate code comments

* Apply suggestions from code review

---------

Co-authored-by: Jiacai Liu <dev@liujiacai.net>
  • Loading branch information
mumu-lhl and jiacai2050 authored Mar 3, 2024
1 parent 89aaed7 commit 5e9727c
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 45 deletions.
19 changes: 10 additions & 9 deletions 02-language-overview-part1.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Zig 代码如下所示:
```zig
const std = @import("std");
// This code won't compile if `main` isn't `pub` (public)
// 如果 `main` 不是 `pub` (public),此代码将无法编译
pub fn main() void {
const user = User{
.power = 9001,
Expand Down Expand Up @@ -87,7 +87,7 @@ const MAX_POWER = user.MAX_POWER
下面这行 Zig 代码是一个注释:

```zig
// This code won't compile if `main` isn't `pub` (public)
// 如果 `main` 不是 `pub` (public),此代码将无法编译
```

Zig 没有像 C 语言中类似 `/* ... */` 的多行注释。
Expand Down Expand Up @@ -190,10 +190,10 @@ pub const User = struct {
方法只是普通函数,只是说可以用 `struct.method()` 方式调用。以下两种方法等价:

```zig
// call diagnose on user
// 调用 user 的 diagnose
user.diagnose();
// The above is syntactical sugar for:
// 上面代码等价于:
User.diagnose(user);
```

Expand Down Expand Up @@ -271,11 +271,12 @@ pub fn init(name: []const u8, power: u64) User {
```zig
const a = [5]i32{1, 2, 3, 4, 5};
// we already saw this .{...} syntax with structs
// it works with arrays too
// 我们已经在结构体中使用过 .{...} 语法,
// 它也适用于数组
const b: [5]i32 = .{1, 2, 3, 4, 5};
// use _ to let the compiler infer the length
// 使用 _ 让编译器推导长度
const c = [_]i32{1, 2, 3, 4, 5};
```

Expand Down Expand Up @@ -320,7 +321,7 @@ pub fn main() void {
为了解决这个问题,你可能会想要进行以下更改:

```zig
// replace const with var
// const 替换为 var
var b = a[1..end];
```

Expand Down Expand Up @@ -403,7 +404,7 @@ std.debug.print("{s}'s power is {d}\n", .{user.name, user.power});
你可能想知道上面这行代码中需要编译时执行的是什么。`print` 函数的定义要求我们的第一个参数(字符串格式)是编译时已知的:

```zig
// notice the "comptime" before the "fmt" variable
// 注意变量"fmt"前的"comptime"
pub fn print(comptime fmt: []const u8, args: anytype) void {
```

Expand Down
21 changes: 10 additions & 11 deletions 03-language-overview-part2.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ Zig 的控制流很可能是我们所熟悉的,但它与 Zig 语言的其他
Zig 中,`if``else if``else` 也很常见:

```zig
// std.mem.eql does a byte-by-byte comparison
// for a string it'll be case sensitive
// std.mem.eql 将逐字节进行比较,对于字符串来说它是大小写敏感的。
if (std.mem.eql(u8, method, "GET") or std.mem.eql(u8, method, "HEAD")) {
// handle a GET request
// 处理 GET 请求
} else if (std.mem.eql(u8, method, "POST")) {
// handle a POST request
// 处理 POST 请求
} else {
// ...
}
Expand Down Expand Up @@ -156,10 +155,11 @@ while (i < src.len) {
var i: usize = 0;
var escape_count: usize = 0;
// this part
// 改写后的
while (i < src.len) : (i += 1) {
if (src[i] == '\\') {
// +1 here, and +1 above == +2
// 这里 +1,上面也 +1,相当于 +2
i += 1;
escape_count += 1;
}
Expand Down Expand Up @@ -199,7 +199,7 @@ const personality_analysis = blk: {
枚举是带有标签的整数常量。它们的定义很像结构体:

```zig
// could be "pub"
// 可以是 "pub"
const Status = enum {
ok,
bad,
Expand Down Expand Up @@ -341,9 +341,8 @@ if (home) |h| {

```zig
const h = home orelse "unknown"
// or maybe
// exit our function
// 或直接返回函数
const h = home orelse return;
```

Expand Down Expand Up @@ -373,8 +372,8 @@ std.crypto.random.bytes(&pseudo_uuid);
Zig 中错误处理功能十分简单、实用。这一切都从错误集(error sets)开始,错误集的使用方式类似于枚举:

```zig
// Like our struct in Part 1, OpenError can be marked as "pub"
// to make it accessible outside of the file it is defined in
// 与第 1 部分中的结构一样,OpenError 也可以标记为 "pub"
// 使其可以在其定义的文件之外访问
const OpenError = error {
AccessDenied,
NotFound,
Expand Down Expand Up @@ -475,7 +474,7 @@ try action(req, res);
函数同时返回可选类型与错误联合类型的情况并不少见。在推导错误集的情况下,形式如下:

```zig
// load the last saved game
// 载入上次保存的游戏
pub fn loadLast() !?Save {
// TODO
return null;
Expand Down
17 changes: 9 additions & 8 deletions 07-heap-memory-and-allocator.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ fn allocLower(allocator: Allocator, str: []const u8) ![]const u8 {
上面的代码没问题。但以下用法不是:

```zig
// For this specific code, we should have used std.ascii.eqlIgnoreCase
// 对于这个特定的代码,我们应该使用 std.ascii.eqlIgnoreCase
fn isSpecial(allocator: Allocator, name: [] const u8) !bool {
const lower = try allocLower(allocator, name);
return std.mem.eql(u8, lower, "admin");
Expand Down Expand Up @@ -211,7 +211,7 @@ pub const User = struct {
在这种情况下,返回一个 `User`可能更有意义。但有时你会希望函数返回一个指向它所创建的东西的指针。当你想让生命周期不受调用栈的限制时,你就会这样做。为了解决上面的悬空指针问题,我们可以使用`create` 方法:

```zig
// our return type changed, since init can now fail
// 我们的返回类型改变了,因为 init 现在可以失败了
// *User -> !*User
fn init(allocator: std.mem.Allocator, id: u64, power: i32) !*User{
var user = try allocator.create(User);
Expand Down Expand Up @@ -284,7 +284,7 @@ pub fn main() !void {
const T = std.heap.GeneralPurposeAllocator(.{});
var gpa = T{};
// is the same as:
// 等同于:
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
```
Expand Down Expand Up @@ -406,12 +406,12 @@ Test [1/1] test.IntList: add... [gpa] (err): memory address 0x101154000 leaked:
此处有多个内存泄漏。幸运的是,测试分配器准确地告诉我们泄漏的内存是在哪里分配的。你现在能发现泄漏了吗?如果没有,请记住,通常情况下,每个 `alloc` 都应该有一个相应的 `free`。我们的代码在 `deinit` 中调用 `free` 一次。然而在 `init``alloc` 被调用一次,每次调用 `add` 并需要更多空间时也会调用 `alloc`。每次我们 `alloc` 更多空间时,都需要 `free` 之前的 `self.items`

```zig
// existing code
// 现有的代码
var larger = try self.allocator.alloc(i64, len * 2);
@memcpy(larger[0..len], self.items);
// Added code
// free the previous allocation
// 添加的代码
// 释放先前分配的内存
self.allocator.free(self.items);
```

Expand Down Expand Up @@ -490,8 +490,9 @@ const aa = arena.allocator();
var list = try IntList.init(aa);
// I'm honestly torn on whether or not we should call list.deinit.
// Technically, we don't have to since we call defer arena.deinit() above.
// 说实话,我很纠结是否应该调用 list.deinit。
// 从技术上讲,我们不必这样做,因为我们在上面调用了 defer arena.deinit()。
defer list.deinit();
...
Expand Down
30 changes: 13 additions & 17 deletions 09-coding-in-zig.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ const User = struct {
上述代码虽然区分大小写,但无论我们如何完美地输入 `Leto``contains` 总是返回 `false`。让我们通过遍历 `lookup` 打印其值来调试一下:

```zig
// Place this code after the while loop
// 将这段代码放在 while 循环之后
var it = lookup.iterator();
while (it.next()) |kv| {
Expand Down Expand Up @@ -184,7 +184,7 @@ false
对于上述代码,实际上只有一种解决方案:我们的 `lookup` 必须拥有键的所有权。我们需要添加一行并修改另一行:

```zig
// replace the existing lookup.put with these two lines
// 用这两行替换现有的 lookup.put
const owned_name = try allocator.dupe(u8, name);
// name -> owned_name
Expand All @@ -198,9 +198,7 @@ try lookup.put(owned_name, .{.power = i});
唯一的解决办法就是自己释放键值。在这一点上,创建我们自己的 `UserLookup` 类型并在 `deinit` 函数中封装这一清理逻辑可能会比较合理。一种简单的改法:

```zig
// replace the existing:
// defer lookup.deinit();
// with:
// 用以下的代码替换现有的 defer lookup.deinit();
defer {
var it = lookup.keyIterator();
while (it.next()) |key| {
Expand Down Expand Up @@ -367,9 +365,8 @@ pub fn main() !void {
`anytype` 的一个最大缺点就是文档。下面是我们用过几次的 `std.json.stringify` 函数的签名:

```zig
// I **hate** multi-line function definitions
// But I'll make an exception for a guide which
// you might be reading on a small screen.
// 我**讨厌**多行函数定义
// 不过,鉴于你可能在小屏幕上阅读这个指南,因此这里破一次例。
fn stringify(
value: anytype,
Expand Down Expand Up @@ -456,7 +453,7 @@ zig build install -Doptimize=ReleaseSmall -Dtarget=x86_64-windows-gnu
除了默认的『安装』步骤外,可执行文件通常还会增加两个步骤:『运行』和『测试』。一个库可能只有一个『测试』步骤。对于基本的无参数即可运行的程序来说,只需要在构建文件的最后添加四行:

```zig
// add after: b.installArtifact(exe);
// 在这行代码后添加下面的代码: b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
Expand Down Expand Up @@ -501,8 +498,7 @@ Zig 的内置软件包管理器相对较新,因此存在一些缺陷。虽然
首先,新建一个名为 `calc` 的文件夹并创建三个文件。第一个是 `add.zig`,内容如下:

```zig
// Oh, a hidden lesson, look at the type of b
// and the return type!!
// 哦,下面的函数定义中有语法之前没讲过,看看 b 的类型和返回类型!!
pub fn add(a: anytype, b: @TypeOf(a)) @TypeOf(a) {
return a + b;
Expand Down Expand Up @@ -555,8 +551,8 @@ pub fn build(b: *std.Build) !void {
回到我们的 `learning`项目和之前创建的 `build.zig`。首先,我们将添加本地 `calc` 作为依赖项。我们需要添加三项内容。首先,我们将创建一个指向 `calc.zig`的模块:

```zig
// You can put this near the top of the build
// function, before the call to addExecutable.
// 你可以把这些代码放在构建函数的顶部,
// 即调用 addExecutable 之前。
const calc_module = b.addModule("calc", .{
.source_file = .{ .path = "PATH_TO_CALC_PROJECT/calc.zig" },
Expand All @@ -572,7 +568,7 @@ const exe = b.addExecutable(.{
.optimize = optimize,
.root_source_file = .{ .path = "learning.zig" },
});
// add this
// 添加这些代码
exe.addModule("calc", calc_module);
b.installArtifact(exe);
Expand All @@ -583,7 +579,7 @@ const tests = b.addTest(.{
.optimize = optimize,
.root_source_file = .{ .path = "learning.zig" },
});
// add this
// 添加这行代码
tests.addModule("calc", calc_module);
```

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

```zig
// replace this:
// 将这些代码:
const calc_module = b.addModule("calc", .{
.source_file = .{ .path = "calc/calc.zig" },
});
// with this:
// 替换成:
const calc_dep = b.dependency("calc", .{.target = target,.optimize = optimize});
const calc_module = calc_dep.module("calc");
```
Expand Down

0 comments on commit 5e9727c

Please sign in to comment.