requireładuje biblioteki (które nie są jeszcze załadowane), userobi to samo, a dodatkowo odwołuje się do ich przestrzeni nazw clojure.core/refer(więc masz również możliwość używania :excludeitp. tak jak z clojure.core/refer). Oba są zalecane nsraczej do użycia w niż bezpośrednio.
Gdybym potrzebował lib foo, to aby użyć bar w foo, musiałbym za każdym razem pisać foo / bar, prawda? Dlaczego miałbyś chcieć załadować bibliotekę w ns, ale potem nie odsyłać jej do ns? Myślę, że możesz martwić się kolizjami i nie chcesz się martwić o ich godzenie, prawda?
Jegschemesch
12
brak konieczności uzgadniania kolizji to dobry punkt, a bardziej ogólnie istnieje styl programowania, który mówi, że „przestrzenie nazw to świetny pomysł, powinniśmy ich mieć więcej” (z „Zen of Python”) - więc np. ten styl zaleca nie używa "using namespace foo;" w C ++, aby czytelnicy i opiekunowie kodu nie musieli martwić się „skąd pochodzi ten pasek”, ale zamiast tego zobaczą bardziej wyraźne foo :: bar. require (vs use) obsługuje ten styl „jawnych przestrzeni nazw”.
Alex Martelli
2
Alex daje dobrą, ale przestarzałą odpowiedź. Jak @overthink wskazuje poniżej, po udzieleniu tej odpowiedzi idiomatyczne zalecenia clojure wymagają nadmiernego użycia. patrz: dev.clojure.org/jira/browse/CLJ-879
Phil Cooper
Chociaż jest to przyjęta i najbardziej pozytywna odpowiedź, jest stara i przedstawia przestarzały pogląd. Lepszą odpowiedzią jest @rzv: stackoverflow.com/a/16429572/172272
Didier A.
65
Dołączanie funkcji zewnętrznych za pomocą requirei jest idiomatyczne refer. Unikasz konfliktów przestrzeni nazw, dołączasz tylko funkcje, których faktycznie używasz / potrzebujesz, i jawnie deklarujesz lokalizację każdej funkcji:
W przeciwnym razie dołączasz wszystko, co sprawia, że jest to zarówno niepotrzebnie duża operacja, jak i bardzo mylące dla innych programistów, aby dowiedzieć się, gdzie znajdują się funkcje.
Bardzo polecam również ten blog jako źródło informacji o przestrzeniach nazw Clojure.
Czy wiesz, czy na końcu jest jakaś różnica między (:use foo :only [bar])i (:require foo :refer [bar])? Wydaje się dziwne, że można to zrobić na dwa sposoby.
przemyślenie
10
Wygląda na to, że stackoverflow.com/a/10370672/69689 odpowiada na moje pytanie. W skrócie: (:require .. :refer ..)to nowy sposób na zrobienie tego samego, który pozwala skutecznie wycofać z użycia :use, co ma pewne wady.
przemyślenie
Dobre przykłady. Uwielbiam przykłady, to miało sens.
Astrid
35
Używanie sure sprawia, że jest to łatwiejsze, ponieważ nie wymaga przeliterowania przestrzeni nazw za każdym razem, gdy chcesz wywołać funkcję, chociaż może również narobić bałaganu, tworząc konflikty przestrzeni nazw. Dobrym punktem pośrednim między „użyj” a „wymagaj” jest „używanie” tylko funkcji z przestrzeni nazw, której faktycznie używasz.
na przykład:
(użyj '[clojure-contrib.duck-streams: only (pisarz czytelnik)])
lub nawet lepiej, określ go na górze pliku w definicji przestrzeni nazw:
(ns com.me.project
(: use [clojure.contrib.test-is: only (deftest to run-tests)]))
Dzięki za dołączenie (kalambur) (ns ...)składni; Szukałem tego, ale wszystkie przykłady, które znalazłem, były proste (use ...).
paul
1
AKTUALIZACJA: ta metoda została teraz przestarzała na korzyść(require '[namepase :refer [var-name1 var-name2]])
Arthur Ulfeldt
@ArthurUlfeldt Możesz zaktualizować swoją odpowiedź, dodając (kalambur) to.
bfontaine
20
Jak już wspomniano, duża różnica polega na tym (require 'foo), że z , następnie odwołujesz się do nazw w przestrzeni nazw biblioteki w ten sposób: (foo/bar ...)jeśli to zrobisz (use 'foo), znajdują się one teraz w twojej bieżącej przestrzeni nazw (cokolwiek to może być i pod warunkiem, że nie ma konfliktów) i możesz wywołać im się podoba (bar ...).
Odpowiedzi:
require
ładuje biblioteki (które nie są jeszcze załadowane),use
robi to samo, a dodatkowo odwołuje się do ich przestrzeni nazwclojure.core/refer
(więc masz również możliwość używania:exclude
itp. tak jak zclojure.core/refer
). Oba są zalecanens
raczej do użycia w niż bezpośrednio.źródło
Dołączanie funkcji zewnętrznych za pomocą
require
i jest idiomatycznerefer
. Unikasz konfliktów przestrzeni nazw, dołączasz tylko funkcje, których faktycznie używasz / potrzebujesz, i jawnie deklarujesz lokalizację każdej funkcji:Nie muszę wywoływać tej funkcji, poprzedzając ją jej przestrzenią nazw:
Jeśli nie używasz
refer
, musisz poprzedzić go przestrzenią nazw:Jeśli wybierzesz
use
zamiast tego, (prawie) zawsze używajonly
:W przeciwnym razie dołączasz wszystko, co sprawia, że jest to zarówno niepotrzebnie duża operacja, jak i bardzo mylące dla innych programistów, aby dowiedzieć się, gdzie znajdują się funkcje.
Bardzo polecam również ten blog jako źródło informacji o przestrzeniach nazw Clojure.
źródło
(:use foo :only [bar])
i(:require foo :refer [bar])
? Wydaje się dziwne, że można to zrobić na dwa sposoby.(:require .. :refer ..)
to nowy sposób na zrobienie tego samego, który pozwala skutecznie wycofać z użycia:use
, co ma pewne wady.Używanie sure sprawia, że jest to łatwiejsze, ponieważ nie wymaga przeliterowania przestrzeni nazw za każdym razem, gdy chcesz wywołać funkcję, chociaż może również narobić bałaganu, tworząc konflikty przestrzeni nazw. Dobrym punktem pośrednim między „użyj” a „wymagaj” jest „używanie” tylko funkcji z przestrzeni nazw, której faktycznie używasz.
na przykład:
lub nawet lepiej, określ go na górze pliku w definicji przestrzeni nazw:źródło
(ns ...)
składni; Szukałem tego, ale wszystkie przykłady, które znalazłem, były proste(use ...)
.(require '[namepase :refer [var-name1 var-name2]])
Jak już wspomniano, duża różnica polega na tym
(require 'foo)
, że z , następnie odwołujesz się do nazw w przestrzeni nazw biblioteki w ten sposób:(foo/bar ...)
jeśli to zrobisz(use 'foo)
, znajdują się one teraz w twojej bieżącej przestrzeni nazw (cokolwiek to może być i pod warunkiem, że nie ma konfliktów) i możesz wywołać im się podoba(bar ...)
.źródło