web-dev-qa-db-fra.com

différence entre l'utilisation et l'exigence

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?

148
Jegschemesch

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.

97
Alex Martelli

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.

59
rzv

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)])) 
33
Arthur Ulfeldt

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 ...).

18
Chris