Skip to Content

条件分支(If)

if 有四种用法:条件语句、条件表达式、条件绑定、类型测试入口。条件位只收 bool,整数或任何其他类型都不允许在条件位。

if、elif、else

func Grade(score: int) -> string { if score >= 90 { return "优"; } elif score >= 75 { return "良"; } elif score >= 60 { return "及格"; } else { return "不及格"; } } print(Grade(95), Grade(80), Grade(65), Grade(50));
优 良 及格 不及格
  • 条件外的括号可写可不写,if (x > 0) 与 if x > 0 等价。
  • 多路分支用 elif。else if 不存在,写了两词形式报 MS2016。
  • 条件为真但分支为空时,块体写 { }。

if 表达式

if 用在值位时是表达式,两臂类型须一致,并且 else 强制:

val label = if 5 > 3 { "成立" } else { "不成立" }; print(label);
成立

块体的最后一个表达式就是分支的值,单句表达式语句可以省分号。elif 链同样能当表达式用,末尾照旧必须有 else:

val w = if n < 0 { "负" } elif n == 0 { "零" } else { "正" };

if val 与 if var:条件绑定

if val 模式 = 表达式 把表达式按模式拆开,匹配成功则进入块,绑定在块内可见,失败则走 else:

var maybe: int? = 42; if val n = maybe { print("拿到", n); } else { print("空"); } maybe = null; if val n = maybe { print("拿到", n); } else { print("空"); }
拿到 42 空
  • val 绑定只读,var 绑定在块内可改写。
if var m = 7 { m = 8; print("var 绑定可改写", m); }
var 绑定可改写 8
  • 模式位支持模式一页的全部形态,不止判空一种。
  • 绑定变量只在绑定块内有效,else 块里拿不到,因为匹配已经失败。

is 声明模式

x is T p 在条件位测试类型并把 p 绑定为收窄后的值:

val box: any = "一段文本"; if box is string t { print("长度", t.Length); }
长度 4

t 在块内是 string,可以直接取成员。这个形态只认直条件和 && 链:取反写法 !(x is T p) 和纯 bool 位(val b = x is T p;)都被拒绝。

guard:只有 else 块的 if

只有 else 块、没有 then 块的 if 是 guard(守护):else 块必须发散:以 return / fail / crash 结尾(循环体内可用 break / continue)。能执行到 guard 之后,就意味着条件成立:

func Read(b: Box?) -> int { if (b != null) else { return -1; } return b.v; // b 在此按非空对待,判空收窄对 guard 直通 }

条件位也可以是 val / var / const 绑定(模式匹配形,承接已退役的 expect 语义):模式匹配成功则绑定变量在 guard 之后可用,失败走 else:

enum Result { Ok(value: int), Bad, } error DemoNeedsOk(); func Demo(r: Result) -> int { if val Result.Ok(n) = r else { crash new DemoNeedsOk(); } return n * 2; }

guard 的两条纪律:

  • else 强制发散:“能走到后面 = 条件成立”是收窄和绑定可见性的依据,不是语法糖;
  • 模式必须可反驳:if val n = 42 else { ... } 这种永不失配的绑定带 else 会报 MS4245(去掉 else 或换变体/字面量模式)。

与 if 的分工:常规 if 表达”两条路都正常”,guard 表”这条路不通就离开”。前置条件检查、参数验证、解包断言用 guard。

注意

  • 判空收窄不限于 if val:if maybe == null else { return; } 这类守护式之后,maybe 在后续代码里按非空类型对待。
  • 装箱标量(int? 等)走 == null 判断时不做收窄,判空绑定请用 if val。
  • if 表达式做多路分类时不如 match 直白,三个以上分支建议换 match。
最后更新于 2026年10月9日