文章目录

Scheme 条件语句:if、cond、case

发布于 2026-04-02 02:16:12 · 浏览 10 次 · 评论 0 条

Scheme 提供了三种主要的条件语句:ifcondcase。它们用于根据表达式的真假值选择不同的执行路径。理解这三者的区别和适用场景,能让你写出更清晰、更符合 Scheme 风格的代码。


使用 if 处理二选一逻辑

if 是最简单的条件结构,适用于只有“真”和“假”两种结果的情况。

语法格式

(if <条件表达式> <为真时执行的表达式> <为假时执行的表达式>)

注意if 必须提供三个部分——条件、真分支、假分支。不能省略假分支。

  1. 编写一个判断正数的函数

    (define (positive-or-not x)
      (if (> x 0)
          "positive"
          "not positive"))
    • x 大于 0 时,返回 "positive"
    • 否则返回 "not positive"
  2. 嵌套 if 实现多分支(不推荐)

    (define (sign x)
      (if (> x 0)
          1
          (if (< x 0)
              -1
              0)))
    • 虽然可行,但嵌套会使代码难以阅读。此时应改用 cond

使用 cond 处理多分支选择

cond 是处理多个条件分支的首选方式,结构清晰,可读性强。

语法格式

(cond
  (<条件1> <结果1>)
  (<条件2> <结果2>)
  ...
  (else <默认结果>))

每个子句是一个括号包裹的列表,包含一个条件和一个或多个表达式。一旦某个条件为真,就执行其对应的结果表达式,并返回最后一个表达式的值。else 子句作为兜底选项,必须放在最后。

  1. 重写 sign 函数使用 cond

    (define (sign x)
      (cond
        ((> x 0) 1)
        ((< x 0) -1)
        (else 0)))
  2. cond 子句中执行多个表达式

    (define (check-grade score)
      (cond
        ((>= score 90)
         (display "Excellent!\n")
         'A)
        ((>= score 80)
         (display "Good job.\n")
         'B)
        (else 'F)))
    • 每个分支可以包含多个表达式,按顺序执行,返回最后一个表达式的值。
  3. 避免遗漏 else 导致未定义行为

    • 如果所有条件都不满足且没有 elsecond 返回未指定值(通常显示为 #<void> 或类似)。务必添加 else 分支以确保程序健壮。

使用 case 基于精确值进行分发

case 适用于根据某个表达式的具体值(通常是符号、数字或字符串)选择分支。它内部使用 equal? 进行比较。

语法格式

(case <表达式>
  ((值1 值2 ...) <结果1>)
  ((值3 值4 ...) <结果2>)
  ...
  (else <默认结果>))
  • <表达式> 先被求值,然后与每个子句中的值列表进行匹配。
  • 匹配成功时,执行对应的结果表达式。
  • else 同样作为默认分支,必须放在最后。
  1. 根据星期几返回工作状态

    (define (work-day? day)
      (case day
        ((mon tue wed thu fri) #t)
        ((sat sun) #f)
        (else (error "Invalid day"))))
    • 输入 montue 等符号时返回 #t(是工作日)。
    • 输入 satsun 返回 #f
    • 其他输入抛出错误。
  2. 匹配数字范围(注意:case 不支持范围,仅支持离散值)

    (define (digit-name d)
      (case d
        ((0) "zero")
        ((1) "one")
        ((2) "two")
        (else "unknown digit")))
    • 不能写成 ((0 1 2)) 表示范围,这里 (0 1 2) 表示匹配 0、1 或 2 中任意一个值。
    • 若需范围判断(如 0–9),应使用 cond 配合 <=>=
  3. case 的限制

    • 只能匹配字面量(literals),不能使用变量或表达式作为匹配项。
    • 例如,以下写法是错误的
      (define x 5)
      (case 5
        ((x) "matched")) ; 错误!这里匹配的是符号 'x',不是变量 x 的值

三者对比与选择建议

结构 适用场景 条件类型 默认分支 多表达式支持
if 二选一 任意布尔表达式 必须显式提供 否(单表达式)
cond 多条件分支 任意布尔表达式 可选(推荐加 else
case 精确值分发 字面量列表(用 equal? 比较) 可选(推荐加 else

选择原则

  1. 只有两个结果?使用 if
  2. 需要判断多个不相关的条件(如 x > 0y < 10(null? lst))?使用 cond
  3. 根据一个表达式的具体值(如 'start'stop42)做选择?使用 case

避免常见错误

  • 不要用 case 判断范围或复杂条件。例如,判断成绩等级应使用 cond,而非试图在 case 中列出所有分数。
  • 不要在 if 中省略 else 分支,除非你明确知道后果(比如只关心副作用且 false 时无需操作)。
  • 不要在 condcase 中遗漏 else,除非你能保证所有可能情况都被覆盖。

实战示例:统一处理用户输入

假设你要解析用户输入的命令,可能是 'start'stop'restart 或无效命令。

(define (handle-command cmd)
  (case cmd
    ((start)
     (display "Starting service...\n")
     'started)
    ((stop)
     (display "Stopping service...\n")
     'stopped)
    ((restart)
     (handle-command 'stop)
     (handle-command 'start)
     'restarted)
    (else
     (display "Unknown command: ")
     (write cmd)
     (newline)
     'error)))
  • 使用 case 因为命令是离散的符号。
  • restart 分支调用了两次 handle-command,展示了 case 支持多表达式。
  • else 分支处理非法输入,保证程序不会静默失败。

记住if 用于简单二分,cond 用于通用多条件,case 用于值匹配。根据问题本质选择最合适的结构,代码自然简洁可靠。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文