Clojure中def是否保存函数返回值 还是每次调用都重新求值?
Clojure def 绑定的求值规则结论
def 定义顶级Var时,会立即对右侧绑定的表达式求值并存储结果,后续读取该Var时不会重复执行原表达式。
你的代码场景具体说明
你给出的两段代码并不等价,差异如下:
- 首先定义函数:
(defn func [a] a)
- 执行
(def funcUsage (func 5))时,Clojure会当场执行(func 5)拿到返回值5,再把5绑定到funcUsage上,这一步func仅被调用1次。 - 后续两次执行
(println funcUsage):都是直接读取funcUsage已经存储的5,不会再触发func的调用,全程func总共只调用1次。 - 而两次执行
(println (func 5)):每次都会当场执行(func 5),func总共会被调用2次。
简易验证方式
你可以给func加调用日志直观验证差异:
(defn func [a] (println "func 触发调用") a) ;; 执行这行时就会打印一次「func 触发调用」 (def funcUsage (func 5)) ;; 执行以下两行仅会打印两次5,不会再输出func的调用日志 (println funcUsage) (println funcUsage) ;; 执行以下两行每行都会先打印「func 触发调用」再打印5,共新增2次调用 (println (func 5)) (println (func 5))
如果需要实现「每次读取时才执行表达式」的延迟求值效果,可以搭配delay和deref(或@语法糖)使用。
内容的提问来源于stack exchange,提问作者Doom599
相关产品推荐
相关产品推荐

