Quelqu'un peut-il expliquer la différence entre use
et require
, à la fois lorsqu'il est utilisé directement et au fur :use
et à mesure :require
dans la ns
macro?
Quelqu'un peut-il expliquer la différence entre use
et require
, à la fois lorsqu'il est utilisé directement et au fur :use
et à mesure :require
dans la ns
macro?
Réponses:
require
charge les bibliothèques (qui ne sont pas déjà chargées), use
fait la même chose et 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 réellement / dont vous 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 besoin d'appeler cette fonction en la préfixant avec son espace de noms:
(wrap-reload) ; works
Si vous ne l'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 à la use
place, utilisez (à peu près) 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éroutante pour les autres programmeurs de trouver où se trouvent les fonctions.
En outre, je recommande vivement ce blog comme ressource pour en savoir plus sur les espaces de noms Clojure.
(:use foo :only [bar])
et (:require foo :refer [bar])
? Cela semble étrange d'avoir deux façons de faire cela.
(:require .. :refer ..)
c'est une nouvelle façon de faire la même chose qui vous permet de déprécier efficacement :use
, ce qui présente quelques inconvénients.
Utiliser sure facilite les choses en ne vous obligeant pas à épeler l'espace de noms à chaque fois que vous voulez appeler une fonction, bien que cela puisse aussi faire un désordre en créant des conflits d'espace de noms. Un bon compromis entre «utiliser» et «exiger» est de n'utiliser que les fonctions d'un espace de noms que vous utilisez réellement.
par exemple:
(utilisez '[clojure-contrib.duck-streams: only (writer reader)])ou mieux encore, spécifiez-le en haut du fichier dans la définition de l'espace de noms:
(ns com.me.project (: use [clojure.contrib.test-is: only (deftest est run-tests)]))
(ns ...)
syntaxe; J'avais cherché cela, mais tous les exemples que j'ai trouvés étaient simples (use ...)
.
(require '[namepase :refer [var-name1 var-name2]])
Comme cela a été mentionné, la grande différence est qu'avec (require 'foo)
, vous faites alors référence aux noms dans l'espace de noms de la lib comme ceci: (foo/bar ...)
si vous le faites, (use 'foo)
ils sont maintenant dans votre espace de noms actuel (quoi qu'il en soit et à condition qu'il n'y ait pas de conflit) et vous pouvez appeler eux aiment (bar ...)
.