Clojure'de Dozq ve For Arasındaki Fark


106

Dozq ve Clojure'de for arasındaki fark nedir? Birini diğerine tercih edeceğiniz zamanların bazı örnekleri nelerdir?

Yanıtlar:


168

Aradaki fark, fortembel bir dizi oluşturması ve bunu doseqyan etkileri yürütmek için döndürmesi ve sıfır döndürmesidir.

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

Diğer dizilere göre yeni bir dizi oluşturmak istiyorsanız, için kullanın. Bazı sekanslardan gelen öğelere dayalı yan etkiler (yazdırma, veritabanına yazma, nükleer savaş başlığı başlatma vb.) Yapmak istiyorsanız, dozq kullanın.


11
şimdi bu çok fazla yan etki ... nükleer bir savaş başlığı fırlatmak :)
Marc

6
Teşekkürler! Nükleer savaş başlıklarımı hiçbir zaman öğe listemde ateşlememesi için (uzun zamandır gitmiş) saçlarımı çekmiştim. "Dozq" kesinlikle yaptı.
Yu Shen

Bu, farkı ortaya koymanın harika bir yoludur.
jskulski

60

Ayrıca doseqtembelken hevesli olduğunu da unutmayın for. Rayne'in cevabında eksik olan örnek şudur:

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

REPL'de, bu genellikle istediğinizi yapar, ancak bu temelde bir tesadüf: REPL, tarafından üretilen tembel diziyi forzorlayarak baskıların gerçekleşmesine neden olur. Etkileşimli olmayan bir ortamda hiçbir şey basılmayacaktır. Bunu sonuçlarını karşılaştırarak görebilirsiniz.

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

Çünkü defformu yeni oluşturulan /var,...vb değil kendisine bağlı olduğu değer döndürür, orada yazdırmak için repl için yok ve bekleyen lazygerçekleşmemiş bir tembel-seq sevk edecektir: kendi elemanlarının hiçbiri hiç bilgisayarlı edilmiştir. eagerbaşvuracak nilve tüm baskısı yapılmış olacaktır.


Dozq, sonsuz tembel dizi değerlendirmesini nasıl ele alır? kötü bir fikir? ister hevesli ister tembel olsun, yalnızca sonlu diziler için mi çağırırsınız?
johnbakers

@johnbakers Değerlendirme kesilene kadar sonsuza kadar engellenecektir. Clojure asla sonsuz dizileri sonlu dizilerden farklı bir şekilde ele almaya çalışmaz.
Radon Rosborough
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.