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:根本没有任何元素被计算出来。 eager
指nil
,所有的印刷工作都会完成。