PAYATHON 2026

Clojure 如何打印中间值并保留表达式结果?

数据阿明

结论

可以用标准库宏 doto 打印一个值,同时让表达式继续返回这个值。给出的例子可以写成:

(* (+ 5 10)
   (- 8 (doto (* 0.5 6) println)))

doto 先求值 (* 0.5 6),再把结果传给 println,最后返回原值。因此,外层计算拿到的是 3.0,而不是 println 返回的 nil。

doto 的用法

println 用于打印,返回值是 nil。如果需要调用一个或多个操作,同时保留原值,可以用 Clojure 标准库中的宏 doto:

(doto 表达式
  函数名)

例如:

(doto (* 0.5 6) println)

这段代码先保存表达式的值,再执行 (println 值),最后返回保存的值。调用也可以写成列表形式:

(doto (* 0.5 6)
  (println))

关于 #$ 写法

#$(* 0.5 6) 不是 Clojure 内置的打印形式。Clojure 读取器支持带标签的字面量,但读取器扩展是在读取代码时处理的,不等于一个能在运行时求值、打印并返回结果的通用调试包装器。这个场景用 doto 更直接。如果需要专用的 spy 形式,也可以自行定义宏,让它在运行时求值、打印并返回原值。

注意事项

doto 返回传入的原值,不会返回打印函数的结果。传入的表达式如果有副作用,仍会按正常的求值规则执行一次。

备注:内容仅供参考。