Cosejureにおけるdoseqとforの違い


回答:


167

違いは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を使用します。


11
今それは多くの副作用です...核弾頭を発射します:)
Marc

6
ありがとう!私の(長い去った)髪を引っ張っていたのは、私のリストの核弾頭を決して発射しないためです。「doseq」は確かにした。
Yu Shen

これは区別するための素晴らしい方法です。
jskulski、2015

60

それdoseqfor怠けている間それが熱心であることに注意してください。レインの答えに欠けている例は

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

REPLでは、これは通常、あなたが望むことを行いますが、それは基本的に偶然ですfor。REPLは、によって生成される遅延シーケンスを強制し、printlnを発生させます。非インタラクティブ環境では、何も印刷されません。の結果を比較することで、これを実際に見ることができます

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未実現怠惰-seqのを参照します。その要素のどれもがすべてで計算されていません。eagerはを参照しnil、その印刷はすべて行われます。


doseqは無限遅延シーケンスの評価をどのように処理しますか?悪いアイデア?熱心なまたは怠惰な有限シーケンスでのみそれを呼び出しますか?
johnbakers 2014年

@johnbakers評価が中断されるまで永久にブロックされます。Clojureは、有限シーケンスとは異なる方法で無限シーケンスを処理しようとはしません。
Radon Rosborough、2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.