基础用法
Zero 中的 if 和其他 C 系语言中的 if 大体相同,只有一个明显的限制:条件必须是 bool。
条件 value == 42 是 bool,因为两个 i32 之间的 == 会返回 bool。两个分支各自包含一个语句块。else 是可选的,所以某个分支可以算是省略掉;但当两个分支都存在时,它们都必须是 { ... } 代码块。
条件必须是 bool
有些语言允许你写 if value { ... },并把 0、"" 或 null 当作假值。Zero 不允许。条件必须是真正的 bool。
let count = 0
if count { // compile error: expected bool, got i32
// ...
}
if count == 0 { // OK
check world.out.write("nothing to do\n")
}
原因和这门语言其他地方的理念一样:显式胜过隐式。智能体读到第二种写法时,能确切知道检查的是什么。第一种写法把真假值规则藏了起来,而且这些规则在不同语言中各不相同,所以 Zero 干脆不支持。
Else 和 Else-If
条件为假时,执行 else 子句:
用 else if 串联多个条件:
if value < 0 {
check world.out.write("negative\n")
} else if value == 0 {
check world.out.write("zero\n")
} else {
check world.out.write("positive\n")
}
else if 其实就是省略了花括号的 else { if ... }:语义相同,缩进更少。最后的 else 是可选的。
条件从哪里来
条件可以是任何结果为 bool 的东西:
- 一个
bool绑定:if ok { ... }。 - 一个比较:
if value == 42 { ... }、if x < y { ... }。 - 一个逻辑组合:
if a && b { ... }、if pair.left == 1_u8 && pair.right == 2_u8 { ... }。 - 一个返回
bool的函数调用:if isReady(world) { ... }。
下面是这门语言示例中的一段真实代码:
let pair: BytePair = Pair { left: 1_u8, right: 2_u8 }
if pair.left == 1_u8 && pair.right == 2_u8 {
check world.out.write("type alias ok\n")
} else {
check world.out.write("type alias broke\n")
}
&& 的短路行为和你预期的一样:如果左侧是 false,就不会计算右侧。|| 也一样。
什么时候改用 match
if/else if 链适合二选一或三选一的判断,尤其是各个条件之间没有共同结构的时候。但如果你要根据和类型的变体做分支,比如 choice 或 枚举,match 才是合适的工具。
对比一下:
// match - exhaustive, compiler-checked
match result {
.ok => value { check world.out.write("ok\n") }
.err => message { check world.out.write("err\n") }
}
和
// if/else over a sum type - verbose and easier to get wrong
if result.isOk() {
let value = result.unwrap()
check world.out.write("ok\n")
} else {
check world.out.write("err\n")
}
match 的写法把变体分析写得清清楚楚,而且以后如果新增了变体而你忘了处理,编译器会报错。if 的写法则会把所有不是 ok 的情况悄悄交给 else 分支,包括你从没考虑过的新变体。
经验法则:布尔值用 if,变体用 match。
风格建议
几个小约定,能让代码对人类和智能体都更容易阅读:
- 函数体总是加花括号。即使只有一行,也要放在
{ ... }里。Zero 没有省略花括号的单语句写法。这是有意为之:它让缩进始终可靠,也消除了 C 系语言中一个常见的 bug 来源。 - 把最常见的分支放在最前面。读者(和智能体)都是从上往下浏览的。
- 在同样清楚的情况下,优先使用正面条件。其他条件相同时,
if isReady比if !notReady更容易理解。
下一步:While 循环
条件语句决定做什么,循环决定做多少次。下一篇文档介绍 Zero 的 while 循环,这是这门语言早期版本自带的循环结构。
常见问题
Zero 中的 if 语句怎么用?
使用 if condition { ... },可以选择加上 else { ... } 子句。条件必须是 bool:Zero 不会把整数、字符串或其他值隐式转换为布尔值。示例:if value == 42 { check world.out.write("yes\n") } else { check world.out.write("no\n") }。
Zero 有三元运算符吗?
Zero 有意保持语言表面积小,使用 if / else 代码块,而不是单独的 condition ? a : b 三元运算符。官方示例即使在简短的情况下也倾向于写明确的分支。如果语言以后支持把 if 当作表达式,Zero 大概也会朝这个方向发展,而不是引入第二种语法。
Zero 中可以链式使用 if/else if 吗?
可以。在分支之间写 else if 就能串联条件:if a { ... } else if b { ... } else { ... }。如果要对 choice 或 enum 做更复杂的分支,请改用 match:它更完备,编译器还会检查你是否处理了每个变体。
为什么 Zero 不把值隐式转换为 bool?
Zero 的设计理念是“一切都是显式的”。隐式真假值(把 0、"" 或 null 当作 false)是 bug 的常见来源,智能体也很难对它进行精确推理。要求条件必须是真正的 bool,能让分支判断在源代码中一目了然,也更容易机械地验证。
什么时候该用 match 而不是 if/else?
当你要根据 choice 或 enum 的变体做分支时,就用 match。编译器能验证你覆盖了每一种情况,而 if/else if 链做不到。if/else 留给简单的布尔判断:相等检查、比较,以及简短的二选一分支。