doall dorun doseq和for的功能有什么区别?

时间:2014-08-15 13:34:21

标签: clojure

函数doalldorundoseqfor之间有什么区别?

我发现一些信息散布在整个互联网上,但我认为最好将这些信息集中在这里。

2 个答案:

答案 0 :(得分:53)

dorundoalldoseq都是为了强制延迟序列,可能是为了产生副作用。

  • dorun - 强制时不要在内存中保留整个seq,返回nil
  • doall - 在强制中保持整个seq(即所有)并返回seq
  • doseq - 与dorun相同,但是有机会对每个元素进行强制执行;返回nil

for的不同之处在于它是列表理解,与强制效果无关。 doseqfor具有相同的绑定语法,这可能会引起混淆,但doseq始终返回nilfor返回惰性seq。

答案 1 :(得分:18)

通过查看(简化的)源代码,您可以了解dorundoall之间的关系:

(defn dorun [coll]
  (when (seq coll) (recur (next coll))))

(defn doall [coll] (dorun coll) coll)
  • dorun贯穿整个序列,忘了它, 最终返回nil
  • doall返回其序列参数,现在由dorun实现。

同样,我们可以在doseqdorun方面实施for

(defmacro doseq [seq-exprs & body]
  `(dorun (for ~seq-exprs ~@body)))

出于某种原因,或许表现,这是没有做到的。标准doseq已完整写出,模仿for