剂量q和Clojure之间的差异

时间:2011-01-18 14:46:22

标签: clojure

doseq和Clojure之间有什么区别?当你选择使用一个而不是另一个时,有哪些例子?

2 个答案:

答案 0 :(得分:153)

不同之处在于for构建了一个惰性序列并返回它,而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

如果要基于其他序列构建新序列,请使用for。如果你想根据某些序列中的元素进行副作用(打印,写入数据库,发射核弹头等),请使用doseq。

答案 1 :(得分:56)

另请注意doseqfor懒惰时非常渴望。 Rayne回答中缺少的例子是

(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形式返回创建的新var,而不是绑定到它的值,所以REPL没有打印,lazy将引用未实现的lazy-seq:它的所有元素都没有计算过。 eager将引用nil,并且所有打印都已完成。

相关问题