条件控制
在 Zig 中,
if
语句的功能非常强大!
基本的 if
、if else
和 else if
语句在此不再赘述,直接看示例:
zig
const num: u8 = 1;
if (num == 1) {
print("num is 1\n", .{});
} else if (num == 2) {
print("num is 2\n", .{});
} else {
print("num is other\n", .{});
}
zig
const print = @import("std").debug.print;
pub fn main() !void {
const num: u8 = 1;
if (num == 1) {
print("num is 1\n", .{});
} else if (num == 2) {
print("num is 2\n", .{});
} else {
print("num is other\n", .{});
}
}
匹配枚举类型
if
语句可以用于枚举类型的匹配,判断是否相等:
zig
const Small = enum {
one,
two,
three,
four,
};
const demo = Small.one;
if (demo == Small.one) {
std.debug.print("{}\n", .{demo});
}
zig
const std = @import("std");
pub fn main() !void {
const Small = enum {
one,
two,
three,
four,
};
const demo = Small.one;
if (demo == Small.one) {
std.debug.print("{}\n", .{demo});
}
}
三元表达式
Zig 中的三元表达式是通过 if else
语句来实现的:
zig
const a: u32 = 5;
const b: u32 = 4;
// 下方 result 的值应该是47
const result = if (a != b) 47 else 3089;
print("result is {}\n", .{result});
zig
const print = @import("std").debug.print;
pub fn main() !void {
const a: u32 = 5;
const b: u32 = 4;
// 下方 result 的值应该是47
const result = if (a != b) 47 else 3089;
print("result is {}\n", .{result});
}
高级用法
以下内容涉及联合类型和可选类型。你可以在阅读完这两章节后再回来学习。
解构可选类型
解构可选类型操作非常简单:
zig
const val: ?u32 = null;
if (val) |real_b| {
_ = real_b;
} else {
try expect(true);
}
以上代码中的 else
分支并非必需。解构后,我们获得的 real_b
是 u32
类型,但请注意,我们捕获的值是只读的!
如果我们想修改值的内容,可以选择捕获对应的指针:
zig
var c: ?u32 = 3;
if (c) |*value| {
value.* = 2;
}
*
运算符表示我们选择捕获这个值对应的指针,因此我们可以通过操作指针来修改其值。
解构错误联合类型
解构错误联合类型类似于解构可选类型:
zig
const val: anyerror!u32 = 0;
if (val) |value| {
try expect(value == 0);
} else |err| {
_ = err;
unreachable;
}
以上代码中 value
的类型为 u32
。else
分支捕获的是错误,即 err
的类型将是 anyerror
(这是由我们之前显式声明的,否则将由编译器推导)。
为了仅检测错误,我们可以这样做:
zig
if (val) |_| {} else |err| {
try expect(err == error.BadValue);
}
同样支持捕获指针来操作值:
zig
var val: anyerror!u32 = 3;
if (val) |*value| {
value.* = 9;
} else |_| {
unreachable;
}
WARNING
那么 if
是如何解构错误联合可选类型的呢?
答案是 if
会先尝试解构错误联合类型,再解构可选类型:
zig
const a: anyerror!?u32 = 0;
if (a) |optional_value| {
try expect(optional_value.? == 0);
} else |err| {
_ = err;
}
以上代码中的 optional_value
是可选类型 ?u32
。我们可以在内部继续使用 if
来解构它。
在错误联合可选类型上也可以使用指针捕获:
zig
var d: anyerror!?u32 = 3;
if (d) |*optional_value| {
if (optional_value.*) |*value| {
value.* = 9;
}
} else |_| {
// nothing
}
以上代码中,*optional_value
捕获的是可选类型的指针。我们在内部尝试解引用后,再次捕获指针来进行操作。