doseq与Clojure之间的区别

doseq和Clojure之间有什么区别? 什么时候你会select使用另一个的例子?

不同的是, for构build一个懒惰的序列并返回它,而doseq是为了执行副作用并返回nil。

 user=> (for [x [1 2 3]] (+ x 5)) (6 7 8) user=> (doseq [x [1 2 3]] (+ x 5)) nil user=> (doseq [x [1 2 3]] (println x)) 1 2 3 nil 

如果你想build立一个基于其他序列的新序列,请使用。 如果你想基于某些序列的元素来做副作用(打印,写入数据库,启动核弹头等),请使用doseq。

注意doseq渴望懒惰。 Rayne的答案中缺less的例子是

 (for [x [1 2 3]] (println x)) 

在REPL中,这通常会做你想做的事情,但这基本上是巧合:REPL强制执行由for产生的惰性序列,导致printlns发生。 在一个非交互式的环境中,什么都不会被打印。 您可以通过比较结果来看到这一点

 user> (def lazy (for [x [1 2 3]] (println 'lazy x))) #'user/lazy user> (def eager (doseq [x [1 2 3]] (println 'eager x))) eager 1 eager 2 eager 3 #'user/eager 

因为def表单返回的是新创build的var,而不是绑定的值,所以REPL没有什么可打印的, lazy会引用一个未实现的lazy-seq:根本没有任何元素被计算出来。 eagernil ,所有的印刷工作都会完成。