条件语句 #
一、if 基础 #
1.1 基本 if 语句 #
zig
const std = @import("std");
pub fn main() void {
const x: i32 = 10;
if (x > 5) {
std.debug.print("x is greater than 5\n", .{});
}
}
1.2 if-else 语句 #
zig
const std = @import("std");
pub fn main() void {
const x: i32 = 3;
if (x > 5) {
std.debug.print("x is greater than 5\n", .{});
} else {
std.debug.print("x is not greater than 5\n", .{});
}
}
1.3 if-else if-else 链 #
zig
const std = @import("std");
pub fn main() void {
const score: i32 = 85;
if (score >= 90) {
std.debug.print("Grade: A\n", .{});
} else if (score >= 80) {
std.debug.print("Grade: B\n", .{});
} else if (score >= 70) {
std.debug.print("Grade: C\n", .{});
} else if (score >= 60) {
std.debug.print("Grade: D\n", .{});
} else {
std.debug.print("Grade: F\n", .{});
}
}
二、if 表达式 #
2.1 if 作为表达式 #
在 Zig 中,if 是表达式,可以返回值:
zig
const std = @import("std");
pub fn main() void {
const x: i32 = 10;
const result = if (x > 5) "big" else "small";
std.debug.print("Result: {s}\n", .{result});
}
2.2 赋值中使用 #
zig
const std = @import("std");
pub fn main() void {
const temperature: i32 = 25;
const status = if (temperature > 30)
"hot"
else if (temperature > 20)
"warm"
else if (temperature > 10)
"cool"
else
"cold";
std.debug.print("Status: {s}\n", .{status});
}
2.3 块表达式 #
zig
const std = @import("std");
pub fn main() void {
const x: i32 = 10;
const result = if (x > 5) blk: {
const doubled = x * 2;
break :blk doubled;
} else blk: {
const halved = x / 2;
break :blk halved;
};
std.debug.print("Result: {}\n", .{result});
}
三、if 与可选类型 #
3.1 解包可选值 #
zig
const std = @import("std");
pub fn main() void {
const maybe_value: ?i32 = 42;
if (maybe_value) |value| {
std.debug.print("Got value: {}\n", .{value});
} else {
std.debug.print("No value\n", .{});
}
}
3.2 可选指针解包 #
zig
const std = @import("std");
fn findItem(id: u32) ?*Item {
if (id == 0) return null;
return &items[id - 1];
}
const Item = struct {
value: i32,
};
var items = [_]Item{
.{ .value = 100 },
.{ .value = 200 },
.{ .value = 300 },
};
pub fn main() void {
if (findItem(2)) |item| {
std.debug.print("Found item with value: {}\n", .{item.value});
item.value *= 2;
std.debug.print("Modified value: {}\n", .{item.value});
} else {
std.debug.print("Item not found\n", .{});
}
}
3.3 if 表达式与可选类型 #
zig
const std = @import("std");
pub fn main() void {
const maybe_name: ?[]const u8 = "Zig";
const name = if (maybe_name) |n| n else "Anonymous";
std.debug.print("Name: {s}\n", .{name});
}
3.4 else if 与可选类型 #
zig
const std = @import("std");
fn getEnvVar(name: []const u8) ?[]const u8 {
if (std.mem.eql(u8, name, "HOME")) return "/home/user";
if (std.mem.eql(u8, name, "PATH")) return "/usr/bin";
return null;
}
pub fn main() void {
const home = getEnvVar("HOME");
const path = getEnvVar("PATH");
const shell = getEnvVar("SHELL");
if (home) |h| {
std.debug.print("HOME: {s}\n", .{h});
} else if (path) |p| {
std.debug.print("PATH: {s}\n", .{p});
} else {
std.debug.print("No known env vars\n", .{});
}
if (shell) |s| {
std.debug.print("SHELL: {s}\n", .{s});
} else {
std.debug.print("SHELL not set\n", .{});
}
}
四、if 与错误联合类型 #
4.1 捕获错误值 #
zig
const std = @import("std");
fn divide(a: i32, b: i32) !i32 {
if (b == 0) return error.DivisionByZero;
return @divTrunc(a, b);
}
pub fn main() void {
const result = divide(10, 2);
if (result) |value| {
std.debug.print("Result: {}\n", .{value});
} else |err| {
std.debug.print("Error: {}\n", .{err});
}
}
4.2 if 表达式与错误 #
zig
const std = @import("std");
fn getValue(maybe_error: bool) !i32 {
if (maybe_error) return error.Failed;
return 42;
}
pub fn main() void {
const result = getValue(false);
const message = if (result) |value|
std.fmt.allocPrint(std.heap.page_allocator, "Success: {}", .{value}) catch "Allocation failed"
else |err|
std.fmt.allocPrint(std.heap.page_allocator, "Error: {}", .{err}) catch "Allocation failed";
defer std.heap.page_allocator.free(message);
std.debug.print("{s}\n", .{message});
}
五、嵌套 if #
5.1 嵌套条件 #
zig
const std = @import("std");
pub fn main() void {
const age: i32 = 25;
const has_license: bool = true;
if (age >= 18) {
if (has_license) {
std.debug.print("Can drive\n", .{});
} else {
std.debug.print("Need a license to drive\n", .{});
}
} else {
std.debug.print("Too young to drive\n", .{});
}
}
5.2 组合条件 #
zig
const std = @import("std");
pub fn main() void {
const age: i32 = 25;
const has_license: bool = true;
const has_insurance: bool = true;
if (age >= 18 and has_license and has_insurance) {
std.debug.print("Fully qualified to drive\n", .{});
} else if (age >= 18 and has_license) {
std.debug.print("Can drive but need insurance\n", .{});
} else if (age >= 18) {
std.debug.print("Need license and insurance\n", .{});
} else {
std.debug.print("Too young\n", .{});
}
}
六、条件表达式 #
6.1 比较运算符 #
zig
const std = @import("std");
pub fn main() void {
const a: i32 = 10;
const b: i32 = 20;
std.debug.print("a == b: {}\n", .{a == b});
std.debug.print("a != b: {}\n", .{a != b});
std.debug.print("a < b: {}\n", .{a < b});
std.debug.print("a <= b: {}\n", .{a <= b});
std.debug.print("a > b: {}\n", .{a > b});
std.debug.print("a >= b: {}\n", .{a >= b});
}
6.2 逻辑运算符 #
zig
const std = @import("std");
pub fn main() void {
const a = true;
const b = false;
std.debug.print("a and b: {}\n", .{a and b});
std.debug.print("a or b: {}\n", .{a or b});
std.debug.print("!a: {}\n", .{!a});
}
6.3 短路求值 #
zig
const std = @import("std");
fn expensiveCheck() bool {
std.debug.print("Checking...\n", .{});
return true;
}
pub fn main() void {
const skip = true;
// and 短路:如果第一个为 false,不评估第二个
if (skip and expensiveCheck()) {
std.debug.print("Both true\n", .{});
}
// or 短路:如果第一个为 true,不评估第二个
if (skip or expensiveCheck()) {
std.debug.print("At least one true\n", .{});
}
}
七、实战示例 #
7.1 输入验证 #
zig
const std = @import("std");
const User = struct {
name: []const u8,
age: u8,
email: ?[]const u8,
};
fn validateUser(user: User) !void {
if (user.name.len == 0) {
return error.EmptyName;
}
if (user.age < 18) {
return error.Underage;
}
if (user.age > 120) {
return error.InvalidAge;
}
if (user.email) |email| {
if (email.len == 0) {
return error.EmptyEmail;
}
if (std.mem.indexOf(u8, email, "@") == null) {
return error.InvalidEmail;
}
}
}
pub fn main() void {
const users = [_]User{
.{ .name = "Alice", .age = 25, .email = "alice@example.com" },
.{ .name = "", .age = 30, .email = null },
.{ .name = "Bob", .age = 15, .email = null },
.{ .name = "Charlie", .age = 200, .email = null },
};
for (users, 0..) |user, i| {
validateUser(user) catch |err| {
std.debug.print("User {}: Validation error - {}\n", .{ i, err });
return;
};
std.debug.print("User {}: Valid\n", .{i});
}
}
7.2 状态机 #
zig
const std = @import("std");
const State = enum {
idle,
connecting,
connected,
disconnecting,
};
fn handleState(state: State, event: Event) State {
return switch (state) {
.idle => if (event == .connect) .connecting else .idle,
.connecting => if (event == .connected) .connected else if (event == .error) .idle else .connecting,
.connected => if (event == .disconnect) .disconnecting else .connected,
.disconnecting => if (event == .disconnected) .idle else .disconnecting,
};
}
const Event = enum {
connect,
connected,
disconnect,
disconnected,
error,
};
pub fn main() void {
var state: State = .idle;
state = handleState(state, .connect);
std.debug.print("State: {}\n", .{state});
state = handleState(state, .connected);
std.debug.print("State: {}\n", .{state});
state = handleState(state, .disconnect);
std.debug.print("State: {}\n", .{state});
state = handleState(state, .disconnected);
std.debug.print("State: {}\n", .{state});
}
八、最佳实践 #
8.1 保持条件简单 #
zig
// 好
if (isValid(user)) {
process(user);
}
// 避免
if (user.name.len > 0 and user.age >= 18 and user.email != null and hasPermission(user)) {
process(user);
}
8.2 使用早返回 #
zig
// 好
fn process(value: ?i32) !void {
const v = value orelse return error.NoValue;
if (v < 0) return error.NegativeValue;
// 处理正常情况
}
// 避免
fn processBad(value: ?i32) !void {
if (value) |v| {
if (v >= 0) {
// 处理正常情况
} else {
return error.NegativeValue;
}
} else {
return error.NoValue;
}
}
8.3 避免深层嵌套 #
zig
// 好:使用早返回
fn processUser(user: ?User) !void {
const u = user orelse return error.NoUser;
if (!u.active) return error.InactiveUser;
if (u.banned) return error.BannedUser;
// 处理正常情况
}
// 避免:深层嵌套
fn processUserBad(user: ?User) !void {
if (user) |u| {
if (u.active) {
if (!u.banned) {
// 处理正常情况
} else {
return error.BannedUser;
}
} else {
return error.InactiveUser;
}
} else {
return error.NoUser;
}
}
const User = struct {
active: bool,
banned: bool,
};
九、总结 #
条件语句要点:
| 特性 | 说明 |
|---|---|
| if 语句 | 基本条件判断 |
| if-else | 双分支 |
| if-else if-else | 多分支 |
| if 表达式 | 可返回值 |
| 可选解包 | if (opt) |v| |
| 错误捕获 | if (err) |v| else |e| |
下一步,让我们学习 switch 语句!
最后更新:2026-03-27