Jaka jest różnica między Doseq a For w Clojure? Jakie są przykłady, kiedy zdecydowałbyś się użyć jednego nad drugim?
105
Różnica polega na tym, że for
buduje leniwą sekwencję i zwraca ją, podczas gdy doseq
służy do wykonywania efektów ubocznych i zwraca 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
Jeśli chcesz zbudować nową sekwencję na podstawie innych sekwencji, użyj for. Jeśli chcesz zrobić efekty uboczne (drukowanie, zapis do bazy danych, wystrzelenie głowicy nuklearnej itp.) W oparciu o elementy z niektórych sekwencji, użyj dawkiq.
Zauważ również, że
doseq
jest chętny, gdyfor
jest leniwy. Przykład, którego brakuje w odpowiedzi Rayne'a toW REPL generalnie zrobi to, co chcesz, ale to w zasadzie zbieg okoliczności: REPL wymusza leniwą sekwencję wytworzoną przez
for
, powodując wystąpienie printlns. W środowisku nieinteraktywnym nic nigdy nie zostanie wydrukowane. Możesz to zobaczyć w akcji, porównując wynikiPonieważ
def
formularz zwraca nowo utworzoną zmienną, a nie wartość, która jest z nią związana, REPL nie ma nic do wydrukowania ilazy
będzie odnosić się do niezrealizowanej sekwencji leniwej: żaden z jej elementów nie został w ogóle obliczony.eager
będzie odnosić sięnil
, a wszystkie jego wydruki zostaną wykonane.źródło