Skip to content

控制流 ​

实现状态: if / else / while / repeat while / for-in / for await in / break / continue / 标签 break/continue / switch / where 守卫 / if case / if let / guard let 全部已实现;fallthrough 拒绝

SYX 控制流与 Swift 风格一致:块用 { } 包裹,模式匹配靠 switch + where 完成。本章按控制结构分类讲解。

条件括号可选: if / while / switch 的条件表达式不强制加 ()。以下两种写法都合法:

swift
if x > 0 { print("pos") }              // 推荐(与 Swift 一致)
if (x > 0) { print("pos") }              // 仍合法(兼容旧代码)

本章正文示例优先使用括号省略的现代风格。

if / else ​

swift,fragment
let x = 1
if x > 0 {
    print("positive")
} else if x == 0 {
    print("zero")
} else {
    print("negative")
}
注意点说明
条件括号可选;if x 与 if (x) 都合法
条件类型必须是 Bool;非 Bool → S004
else if链式合法;无嵌套深度限制
块省略if x { print(x) } 合法(单语句可省 {})

「if 表达式」: Phase 100+ 起 if 可作表达式返回值;用于赋值时两分支必须存在且类型相同。

swift,fragment
let x = 1
let label = if x > 0 { "pos" } else { "non-pos" }

while ​

swift
var x = 10
while x > 0 {
    print(x)
    x = x - 1
}

条件检查在循环体之前;条件为 false 时循环体不执行。

repeat while ​

swift
var n = 0
repeat {
    n = n + 1
    print(n)
} while n < 3

循环体 至少 执行一次;条件在每次迭代后检查。

Swift 对照: Swift 用 repeat { } while …;SYX 相同。Swift 的 do { } while … 形式(不带 repeat)不识别。

for-in ​

swift,fragment
for item in [1, 2, 3] {
    print(item)
}

for c in "abc" {
    print(c)
}

for i in 0..<10 {
    print(i)
}

for await: for await x in asyncSeq { … } 逐个等待异步元素;详见 第 18 章 并发。本章不做 doctest。

可迭代的源:

形式元素类型
Array<T>T
Set<T>T
Dictionary<K, V>(K, V) 元组
StringString(单标量)
0..<nInt
自定义 IteratorString(协议要求)
Object(String, Any)
async sequenceawait 元素类型

for await in ​

for await x in asyncSeq 逐个等待异步元素,详见 第 18 章 并发。

break / continue ​

swift,fragment
var done = false
var skip = false
while true {
    if done {
        break         // 跳出最近循环
    }
    if skip {
        continue      // 进入下一轮
    }
    break
}
形式行为
break跳出 最近一层 循环或 switch
continue跳到 最近一层 循环下一轮
break label跳出指定标签的循环(已实现)
continue label跳到指定标签的循环下一轮(已实现)

标签(label): 语法 label: while (cond) { … break label … };SYX 标签在嵌套循环里识别,但跨函数 / 闭包识别仍演进中。

switch ​

switch 是 SYX 表达多路分支的核心;支持 模式 + 守卫 + exhaustiveness:

swift
enum Box {
    case ok(data: String)
    case err(e: String)
}
let value = Box.ok(data: "hi")
switch value {
case .ok(let data) {
    print(data)
}
case .err(let e) where e.count > 0 {
    print(e)
}
default {
    print("other")
}
}

let num = 5
switch num {
case 1 {
    print("one")
}
case 2, 3, 5, 7 {
    print("small prime")
}
case 0..<10 {
    print("single digit")
}
default {
    print("other")
}
}
形式说明
case pattern模式匹配
case pattern where guard守卫(guard 为真才执行)
case pat1, pat2多模式(| 在 parser 内部,pat1, pat2 写法合法)
case 0..<10范围模式(Range<Int> 上下文)
case .variant(let x)枚举/Result 变体模式
default默认分支;不强制(enum / final class 封闭域时可省略,但有 warning)

switch 块语法(重要) ​

swift
let x = 1
switch x {
case 1 {           // 花括号包裹 case 体;与 Swift 不同
    print("one")
}
case 2 {
    print("two")
}
}

关键点: SYX case 后跟 { } 块,不是 case 1: 单行 + 缩进。早期 Phase 接受 case 1: 写法(与 Swift 一致),但推荐 块式 case 1 { } 风格。

模式(详细) ​

swift
enum Outcome {
    case ok(value: String)
    case err(message: String)
    case failure(code: Int, message: String)
    case empty
}
let result = Outcome.ok(value: "hi")
switch result {
case .ok(let value) {                      // 解构变体
    print("ok: \(value)")
}
case .err(let message) {                   // 命名关联值
    print("err: \(message)")
}
case .failure(code: let c, message: let m) {  // 命名参数解构
    print("fail code=\(c) msg=\(m)")
}
case .empty {                              // 无关联值
    print("empty")
}
default {
    print("other")
}
}

详见 第 9 章 枚举 与 语言参考:模式。

范围 case ​

swift
let n = 42
switch n {
case 0..<10 { print("single digit") }
case 10..<100 { print("two digits") }
case 100..<1000 { print("three digits") }
default { print("large") }
}

闭区间 a...b 部分实现;推荐半开 a..<b + 末尾 Int.max。

exhaustiveness 检查 ​

switch 在 enum / final class / Int / Bool 等封闭域上自动做 exhaustiveness 校验;缺 default 且未覆盖全部 case → S007。

swift
enum Color { case red, green, blue }

func describe(_ c: Color) -> String {
    switch c {
    case .red { return "red" }
    case .green { return "green" }
    case .blue { return "blue" }
    }                                       // ✅ 全覆盖
}

非封闭域(如 String、Any)需 default。

守卫 where ​

swift
let n = 4
switch n {
case let x where x < 0 {
    print("negative: \(x)")
}
case let x where x % 2 == 0 {
    print("even: \(x)")
}
case let x {
    print("odd: \(x)")
}
}

where 表达式必须为 Bool;多 where 与多模式用 , 分隔(parser 接受)。

fallthrough ​

fallthrough 拒绝(编译错误)。SYX case 不 自动 fallthrough;需要在 case 体末尾显式 break(默认行为已是 break,可省略)。

if case ​

swift
enum Box {
    case ok(data: String)
    case err
}
let result = Box.ok(data: "hi")
if case .ok(let data) = result {
    print(data)
} else {
    print("not ok")
}

if case 是 switch 单分支的便捷形式。模式同 switch case。

if let / guard let ​

解包 Optional:

swift
func demoOptional() {
    let optional: Int? = 1
    if let x = optional {
        print("got: \(x)")
    } else {
        print("nil")
    }

    guard let y = optional else {
        return                              // 早退(else 必须退出:return / throw / break / continue)
    }
    print("y is \(y)")                       // 此处 y 已被解包,非 Optional
}
demoOptional()
形式行为
if let x = opt { }非 nil 进入分支,x 是解包后的值;可选 else
if let x = opt, let y = other链式解包(逗号分隔多条件)
guard let x = opt else { … }非 nil 继续;nil 进入 else 必须 退出(return / throw / break / continue / fatalError)
guard let x = opt, cond else多条件 + 守卫

else 必须退出: guard 的 else 块若不退出(缺 return 等)→ 编译错误 S020。

throw ​

swift
import System

func loadFile(path: String) throws -> String {
    if !File.exists(path) {
        throw "not found"
    }
    return File.read(path: path)
}

throw "msg" 抛出字符串异常(MVP 类型)。try / catch 见 第 17 章 错误处理。

早退 ​

SYX 提供 return / throw / break / continue 四种早退路径。函数体内 return 可省(隐式返回 Void):

swift
func maybeDouble(x: Int?) -> Int {
    guard let v = x else {
        return 0                          // ✅ 显式
    }
    return v * 2
}

控制流与闭包 ​

闭包可携带控制流(如 for / if),但 break / continue 默认只作用于最近循环(不能跨闭包边界)。如需跳出外层循环,用 label:

swift
func firstStop(groups: Array<Array<Int>>) -> Int {
    outer: for group in groups {
        for n in group {
            if n < 0 {
                break outer
            }
        }
    }
    return 0
}

func main() {
    print(firstStop(groups: [[1, 2], [-1, 9]]))
}

完整示例 ​

swift
import System

func classify(path: String) -> String {
    if File.exists(path) {
        let content = File.read(path: path)
        let n = content.count

        switch n {
        case 0 { return "empty" }
        case 1..<100 { return "tiny" }
        case 100..<10_000 { return "medium" }
        default { return "large" }
        }
    }
    return "missing"
}

func main() {
    for p in ["/etc/hostname", "/tmp/empty.txt", "/tmp/big.txt"] {
        print("\(p) → \(classify(path: p))")
    }
}

诊断 ​

代码触发修复
P001语法解析错误(括号不匹配、操作符缺失等)检查附近语法
S004if 条件非 Bool显式比较
S007switch 非穷尽(enum / 封闭域)加缺失 case 或 default
S010模式不匹配检查 enum case 是否完整
S020guard let else 未退出加 return / throw 等
R003下标越界检查索引

与 Swift 的差异 ​

SwiftSYX
if x 无括号✅ 一致;if x 与 if (x) 都合法(推荐省略)
switch x✅ 一致;switch x 与 switch (x) 都合法(推荐省略)
case 1: 缩进风格推荐 case 1 { } 块风格
fallthrough拒绝(编译错误)
标签 break label部分实现(演进中)
where case未实现(用 if case 链式)
if #available未实现
do { try … } catch { }用 do { } catch { }(无 do 关键字)

下一章 → 函数

参见 → 语言参考:语句 · 第 7 章 函数 · 第 17 章 错误处理

SYX · Apache-2.0