# 控制流 Deft 的控制流形式与裸函数调用自然地并列(参见 语法与风格)。本页涵盖条件分支、循环、 集合迭代,以及用于清理的 `defer`。 ## `if` / `else` ### 单行形式(简单条件首选)
if ($n == 0) { return 1 }
if logged-in? { set msg "Welcome!" }
set msg [if admin? "Welcome, admin!" "Welcome, user!"]
### 多行形式(复杂逻辑)
if logged-in? {
    "Welcome!"
} else {
    if admin? {
        "Welcome, admin!"
    } else {
        "Welcome, user!"
    }
}
### 条件 条件是括号中的中缀表达式——或者裸的真值/假值。裸括号 `(...)` 不是函数调用(参见 语法与风格)。
if ($count > 10) { ... }                          # ✓ infix condition
if logged-in? { ... }                              # ✓ bare predicate
if $user~active { ... }                            # ✓ field access

if [== $n 0] { ... }                              # ✗ invalid — `==` is infix-only, use ($n == 0)
### 真值性 `nil` 和 `false` 为假值。其他一切(包括 `0`、`""`、 `@{}`、`%{}`)都为真值。
if "" { echo "truthy" }         # prints: truthy
if 0 { echo "truthy" }          # prints: truthy
if nil { echo "nope" }          # no output
## `match` 模式匹配在单个表达式中按形状、类型和内容进行分派。完整参考见 模式匹配。
def classify {|n^number|
    match $n {
        0              => "zero"
        1 .. 9         => "single digit"
        $x when ($x < 0) => "negative"
        _              => "positive"
    }
}
## `for`——遍历集合 `for x in $xs { ... }` 迭代列表、映射、集合、字符串或任何 `ISeq`:
for x in @{ 1 2 3 } {
    echo $x
}
# 1
# 2
# 3

for entry in %{ :a 1 :b 2 } {
    echo "$entry(0) -> $entry(1)"            # map yields @{key value} pairs
}
# a -> 1
# b -> 2

for ch in "abc" { echo $ch }                # string yields single chars
### `break` 与 `continue`
for x in @{ 1 2 3 4 5 } {
    if ($x == 2) { continue }
    if ($x == 4) { break }
    echo $x
}
# 1
# 3
### 索引绑定
for x idx in $xs {
    echo "[$idx] $x"
}
### 用于数值范围的 `range`
for i [range 0 10] { echo $i }              # 0..9
for i [range 1 10 2] { echo $i }            # 1 3 5 7 9
## `while`——带条件的循环
set n 0
while ($n < 5) {
    echo $n
    incr n
}
`while` 最适合无界迭代(解析输入、轮询、退避)。集合迭代 优先使用 `for`。 ## `each`——带副作用的遍历 `each` 是 `for` 的函数形式。在管道中使用它:
@{ 1 2 3 } |> each { echo $it }

%{ :a 1 :b 2 } |> each { echo "$it(0) = $it(1)" }
返回 `nil`。不要把它与 `map` 混淆(后者产生惰性序列)。 ## `defer`——退出时清理 `defer` 调度一个代码块,在外层函数返回时运行,无论是正常返回 还是通过提前 `return`/抛出的错误返回。各 defer 按 后进先出顺序运行。
def with-file {|path^string|
    set fh [fs/open $path "r"]
    defer { fs/close $fh }

    # ... use $fh ...
    # fs/close runs when the function exits, however it exits.
}
### LIFO 顺序
def ordered {|
    defer { echo "first" }
    defer { echo "second" }
    defer { echo "third" }
    "done"
|
}

ordered                  # prints: third, second, first
### 提前返回时的执行
def parse-config {|path^string|
    set raw [unwrap [fs/read $path]]
    defer { echo "parsed $path" }            # runs even on early return
    if (empty? $raw) { return %{} }
    [json/parse $raw]
}
### 作用域独立性 嵌套 `def` 内的 `defer` 只在该嵌套函数返回时触发——defer 绑定到 函数帧,而非代码块:
def outer {|
    defer { echo "outer exits" }
    def inner {||
        defer { echo "inner exits" }
        "inner"
    |
    }
    [inner]
    "outer"
|
}
# inner exits
# outer exits
另见并发,了解 `defer` 在异步资源方面的作用。 ## `try` / `catch`——错误处理
try {
    set result [unwrap [fs/read $path]]
    [json/parse $result]
} catch e {
    echo "failed: $e~message"
    %{}
}
被捕获的值是一个带标签的 `%Err{ :message ... }` 映射。完整的 Result 机制(包括 `ok`/`err`/`?`/`unwrap`)见 错误处理。 ## `throw`——显式错误
def divide {|a b|
    if ($b == 0) { [throw "division by zero"] }
    ($a / $b)
}
抛出的值成为被 `try` 捕获的 `%Err{ :message ... }` 载荷。 ## 提前 `return` `return` 携带给定值立即退出外层函数:
def find-first-positive {|xs^list|
    for x in $xs {
        if ($x > 0) { return $x }
    }
    nil
}
函数内闭包体中的 `return` 仍从外层函数返回,而不是从 闭包返回——闭包不引入新的返回帧。 ## 快速参考 | 形式 | 用途 | |---|---| | `if cond { ... } else { ... }` | 条件分支 | | `match expr { pattern => result ... }` | 基于形状的分派 | | `for x in $xs { ... }` | 遍历集合 | | `for x idx in $xs { ... }` | 带索引遍历 | | `while cond { ... }` | 条件控制的循环 | | `each` | 带副作用的函数式遍历(用于管道) | | `defer { ... }` | 调度清理 | | `try { ... } catch e { ... }` | 错误处理 | | `return value` | 提前退出 | | `break` / `continue` | 循环控制 | | `[macro/compile-when cond body]` | 编译期条件——若 `cond` 为假则省略 `body`(参见宏) |