Skip to content

Commit

Permalink
改进关于 undefined 的说明
Browse files Browse the repository at this point in the history
  • Loading branch information
timothyqiu authored and jinzhongjia committed Sep 7, 2024
1 parent 5769046 commit 90ecd7d
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 8 deletions.
12 changes: 8 additions & 4 deletions course/basic/define-variable.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ outline: deep

如果一定要使用不符合这些规定的名称(例如与外部库的链接),那么请使用 `@""` 语法。

<<<@/code/release/define_variable.zig#indentifier
<<<@/code/release/define_variable.zig#identifier

::: info 🅿️ 提示

Expand All @@ -50,11 +50,15 @@ zig 使用 `const` 作为关键字来声明常量,它无法再被更改,只

<<<@/code/release/define_variable.zig#undefined

::: warning ⚠️ 警告
使用 `undefined` 初始化的变量不会执行任何初始化操作,我们无法预知它的初始值。

因此,`undefined` 常用于初始值不重要的场合。例如,用作缓冲区的变量通常会被提交给另一个函数进行写操作,覆盖原有内容。由于不会对其进行读操作,所以没有必要将这个变量初始化为某个特定的值。

慎重使用 `undefined`,如果一个变量是未定义的,使用它出现无法预知的情况。
<<<@/code/release/define_variable.zig#use-undefined

::: warning ⚠️ 警告

当一个变量未定义时,那么它将不会执行默认的初始化操作,此时变量的值将会是无意义的值(我们绝对不能在赋值前使用它)
慎重使用 `undefined`:如果一个变量的值是未定义的,那么对这个变量进行读操作时,读取到任何值都是可能的,甚至可能读取到对于这个变量所使用的类型而言完全没有意义的值

`Debug` 模式下,Zig 将 `0xaa` 字节写入未定义的内存。这是为了尽早发现错误,并帮助检测调试器中未定义内存的使用。但是,此行为只是一种实现功能,而不是语言语义,因此不能保证代码可以观察到它。
:::
Expand Down
30 changes: 28 additions & 2 deletions course/code/12/define_variable.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub fn main() !void {
DefineVar.main();
Const.main();
Undefined.main();
UseUndefined.main();
Block.main();
}

Expand Down Expand Up @@ -79,7 +80,32 @@ const Undefined = struct {
// #endregion undefined
};

// #region indentifier
const UseUndefined = struct {
// #region use-undefined
const std = @import("std");

// 填充连续递增的数字
// 注意该函数中并没有对 output 进行读操作,所以 output 的初始值不重要
fn iota(init: u8, output: []u8) void {
for (output, init..) |*e, v| {
e.* = @intCast(v);
}
}

pub fn main() void {
// buffer 定义时不需要初始化
var buffer: [8]u8 = undefined;

// 因为 iota() 会为 buffer 里的元素赋值
iota(7, &buffer);

// 输出 { 7, 8, 9, 10, 11, 12, 13, 14 }
std.debug.print("{any}\n", .{buffer});
}
// #endregion use-undefined
};

// #region identifier
const @"identifier with spaces in it" = 0xff;
const @"1SmallStep4Man" = 112358;

Expand All @@ -92,7 +118,7 @@ const Color = enum {
@"really red",
};
const color: Color = .@"really red";
// #endregion indentifier
// #endregion identifier

const Block = struct {
pub fn main() void {
Expand Down
30 changes: 28 additions & 2 deletions course/code/14/define_variable.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub fn main() !void {
DefineVar.main();
Const.main();
Undefined.main();
UseUndefined.main();
Block.main();
}

Expand Down Expand Up @@ -79,7 +80,32 @@ const Undefined = struct {
// #endregion undefined
};

// #region indentifier
const UseUndefined = struct {
// #region use-undefined
const std = @import("std");

// 填充连续递增的数字
// 注意该函数中并没有对 output 进行读操作,所以 output 的初始值不重要
fn iota(init: u8, output: []u8) void {
for (output, init..) |*e, v| {
e.* = @intCast(v);
}
}

pub fn main() void {
// buffer 定义时不需要初始化
var buffer: [8]u8 = undefined;

// 因为 iota() 会为 buffer 里的元素赋值
iota(7, &buffer);

// 输出 { 7, 8, 9, 10, 11, 12, 13, 14 }
std.debug.print("{any}\n", .{buffer});
}
// #endregion use-undefined
};

// #region identifier
const @"identifier with spaces in it" = 0xff;
const @"1SmallStep4Man" = 112358;

Expand All @@ -92,7 +118,7 @@ const Color = enum {
@"really red",
};
const color: Color = .@"really red";
// #endregion indentifier
// #endregion identifier

const Block = struct {
pub fn main() void {
Expand Down

0 comments on commit 90ecd7d

Please sign in to comment.