Quelle est la différence entre doseq et pour Clojure? Quels sont quelques exemples de cas où vous choisiriez d’utiliser l’un plutôt que l’autre?
Réponses
Trop de publicités? La différence est que for
construit une séquence paresseuse et la renvoie, tandis que doseq
sert à exécuter des effets secondaires et renvoie zéro.
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
Si vous souhaitez créer une nouvelle séquence basée sur d’autres séquences, utilisez pour. Si vous souhaitez avoir des effets secondaires (impression, écriture dans une base de données, lancement d'une tête nucléaire, etc.) en fonction d'éléments de certaines séquences, utilisez doseq.
Notez également qu' doseq
a hâte tout en for
est paresseux. L'exemple manquantes dans Rayne réponse est
(for [x [1 2 3]] (println x))
Lors de la RÉPLICATION, ce sera généralement faire ce que vous voulez, mais qui est en fait une coïncidence: le REPL forces les paresseux de la séquence produite par for
, provoquant la printlns arriver. Dans un non-interactive de l'environnement, rien ne sera jamais imprimé. Vous pouvez le voir en action en comparant les résultats de
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
Parce que l' def
formulaire renvoie la nouvelle var créé, et non pas la valeur qui est lié à elle, il n'y a rien pour le REPL à imprimer, et lazy
fait référence à une latents paresseux-seq: aucun de ses éléments ont été calculées à tous. eager
appellerons nil
, et l'ensemble de son impression aura été fait.