文章目录

Scheme 循环:do、for-each、map

发布于 2026-04-03 10:47:01 · 浏览 7 次 · 评论 0 条

Scheme 循环:do、for-each、map

Scheme 语言没有传统意义上的 whilefor 循环,而是通过递归和内置的迭代结构实现重复操作。掌握 dofor-eachmap 是写出简洁高效代码的关键。以下指南将手把手教你正确使用这三种结构。


使用 do 实现通用循环

do 是 Scheme 中最接近传统循环的结构,适合需要显式控制变量更新和终止条件的场景。

  1. 理解基本语法do 的格式为

    (do ((var init update) ...)
        (test result ...)
      body ...)

    其中 var 是循环变量,init 是初始值,update 是每次迭代后的更新表达式;test 为真时循环结束,此时返回 result ... 的值;body ... 是每次迭代执行的操作。

  2. 编写一个从 0 到 n-1 的计数循环
    定义 变量 i 初始为 0,每次加 1,当 i 等于 n 时停止。

    (define (count-up n)
      (do ((i 0 (+ i 1)))
          ((= i n))
        (display i)
        (newline)))

    调用 (count-up 3) 将输出:

    0
    1
    2
  3. 在循环中累积结果:若需返回计算值(而非仅副作用),把结果放在 test 子句后。例如计算阶乘:

    (define (factorial n)
      (do ((i 1 (+ i 1))
           (acc 1 (* acc i)))
          ((> i n) acc)))

    此处 acc 初始为 1,每次乘以当前 i,当 i 超过 n 时返回 acc


使用 for-each 执行副作用

当你有一组数据,只需对每个元素执行操作(如打印、写文件),不关心返回值时,用 for-each

  1. 确认输入是一个列表for-each 只能遍历列表(或其他序列类型,取决于 Scheme 实现),不能直接用于数字范围。

  2. 提供一个过程和一个或多个列表
    调用 (for-each proc list1 list2 ...),其中 proc 接受与列表数量相同的参数。

    (for-each display '(a b c))

    输出:abc(无换行)。

  3. 处理多列表并行遍历

    (for-each (lambda (x y)
                (display x)
                (display ": ")
                (display y)
                (newline))
              '(apple banana cherry)
              '(red yellow red))

    输出:

    apple: red
    banana: yellow
    cherry: red

    注意:所有列表必须等长,否则行为未定义。


使用 map 转换数据并收集结果

map 用于对列表每个元素应用函数,并返回新列表,是函数式编程的核心工具。

  1. 单列表变换
    应用 函数到每个元素,生成结果列表。

    (map (lambda (x) (* x x)) '(1 2 3 4))

    返回:'(1 4 9 16)

  2. 多列表并行映射

    (map + '(1 2 3) '(10 20 30))

    返回:'(11 22 33)。函数 + 同时接收两个列表的对应元素。

  3. 避免副作用:虽然技术上可在 map 中使用 display 等副作用操作,但这是反模式。坚持只在 map 中做纯变换,用 for-each 处理副作用。


选择正确的循环结构

根据你的目标决定使用哪种结构:

场景 推荐结构 原因
需要精细控制循环变量和终止条件 do 提供完整的初始化、测试、更新机制
对每个元素执行操作但不需要返回值(如打印) for-each 语义清晰,明确表示只用于副作用
将列表转换为另一个列表 map 自动收集结果,符合函数式风格

记住:在 Scheme 中,优先使用 mapfor-each;仅当它们无法满足需求(如需要多个状态变量或复杂终止逻辑)时才用 do

评论 (0)

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

扫一扫,手机查看

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