Quelqu'un peut-il expliquer la différence entre use
et require
, à la fois lorsqu'il est utilisé directement et comme :use
et :require
dans la macro ns
?
require
charge les bibliothèques (qui ne sont pas déjà chargées), use
fait de même plus il fait référence à leurs espaces de noms avec clojure.core/refer
(vous avez donc également la possibilité d'utiliser :exclude
etc comme avec clojure.core/refer
). Les deux sont recommandés pour une utilisation dans ns
plutôt que directement.
Il est idiomatique d'inclure des fonctions externes avec require
et refer
. Vous évitez les conflits d'espace de noms, vous n'incluez que les fonctions que vous utilisez/avez réellement besoin et vous déclarez explicitement l'emplacement de chaque fonction:
(ns project.core
(:require [ring.middleware.reload :refer [wrap-reload]]))
Je n'ai pas à invoquer cette fonction en la préfixant avec son espace de noms:
(wrap-reload) ; works
Si vous n'utilisez pas refer
, vous devrez le préfixer avec l'espace de noms:
(ring.middleware.reload/wrap-reload) ; works if you don't use refer in your require
Si vous choisissez use
à la place, (à peu près) utilisez toujours only
:
(ns project.core
(:use [ring.middleware.reload :only [wrap-reload]]))
Sinon, vous incluez tout, ce qui en fait à la fois une opération inutilement volumineuse et très déroutant pour les autres programmeurs pour trouver où vivent les fonctions.
Aussi, je recommande fortement ce blog comme ressource pour en savoir plus sur les espaces de noms Clojure.
Utilisez bien sûr pour le rendre plus facile en ne vous obligeant pas à épeler l'espace de noms à chaque fois que vous voulez appeler une fonction, mais cela peut aussi gâcher les choses en créant des conflits d'espace de noms. Un bon compromis entre "utiliser" et "exiger" consiste à "utiliser" uniquement les fonctions d'un espace de noms que vous utilisez réellement.
par exemple:
(utilisez '[clojure-contrib.duck-streams: seulement (lecteur écrivain)])
(ns com.me.project (: utilisez [clojure.contrib.test-is: seulement (le deftest est des tests d'exécution)]))
Comme cela a été mentionné, la grande différence est qu'avec (require 'foo)
, vous faites ensuite référence aux noms dans l'espace de noms de la lib comme ceci: (foo/bar ...)
si tu fais (use 'foo)
alors ils sont maintenant dans votre espace de noms actuel (quel qu'il soit et à condition qu'il n'y ait pas de conflits) et vous pouvez les appeler comme (bar ...)
.