Apa perbedaan antara doseq dan untuk di Clojure? Apa saja contoh ketika Anda akan memilih untuk menggunakan salah satu dari yang lain?
105
Perbedaannya adalah bahwa for
membangun urutan malas dan mengembalikannya saat doseq
untuk menjalankan efek samping dan mengembalikan nol.
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
Jika Anda ingin membuat urutan baru berdasarkan urutan lain, gunakan untuk. Jika Anda ingin melakukan efek samping (mencetak, menulis ke database, meluncurkan hulu ledak nuklir, dll) berdasarkan elemen dari beberapa urutan, gunakan doseq.
Perhatikan juga yang
doseq
bersemangat saatfor
sedang malas. Contoh yang hilang dalam jawaban Rayne adalahDi REPL, ini biasanya akan melakukan apa yang Anda inginkan, tetapi itu pada dasarnya kebetulan: REPL memaksa urutan malas yang dihasilkan oleh
for
, menyebabkan printlns terjadi. Dalam lingkungan non-interaktif, tidak ada yang akan dicetak. Anda dapat melihat ini beraksi dengan membandingkan hasilKarena
def
formulir mengembalikan var baru yang dibuat, dan bukan nilai yang terikat padanya, REPL tidak akan mencetak apa pun, danlazy
akan merujuk ke lazy-seq yang belum direalisasi: tidak ada elemennya yang telah dihitung sama sekali.eager
akan merujuk kenil
, dan semua pencetakannya akan selesai.sumber