Может ли кто-нибудь объяснить разницу между use
и require
, как при непосредственном использовании, так и в качестве :use
и :require
в макросе ns
?
Разница между использованием и требованием
Ответ 1
require
загружает libs (которые еще не загружены), use
делает то же самое плюс, это относится к их пространствам имен с clojure.core/refer
(так что вы также получаете возможность использовать :exclude
и т.д., например, с помощью clojure.core/refer
). Оба рекомендуется использовать в ns
, а не непосредственно.
Ответ 2
Идиоматично включать внешние функции с require
и refer
. Вы избегаете конфликтов пространства имен, вы включаете только те функции, которые вам действительно нужны/нужны, и вы явно объявляете каждое местоположение функции.
(ns project.core
(:require [ring.middleware.reload :refer [wrap-reload]]))
Мне не нужно вызывать эту функцию, предваряя ее своим пространством имен.
(wrap-reload) ; works
Если вы не используете refer
, вам необходимо обработать его с помощью пространства имен.
(ring.middleware.reload/wrap-reload) ; works if you don't use refer in your require
Если вы выберете use
вместо этого (почти), всегда используйте only
.
(ns project.core
(:use [ring.middleware.reload :only [wrap-reload]]))
В противном случае вы включаете все, что делает его как ненужную большую операцию, так и очень запутанным для других программистов, чтобы найти, где живут функции.
Кроме того, я настоятельно рекомендую этот блог в качестве ресурса для более подробного описания пространств имен Clojure.
Ответ 3
Убедитесь, что это упростит, не требуя, чтобы вы прописали пространство имен каждый раз, когда хотите вызвать функцию, хотя она также может создавать беспорядок, создавая конфликты пространства имен. Хорошей средой между "использованием" и "требованием" является только "использование" функций из пространства имен, которое вы фактически используете.
например:
(use '[clojure-contrib.duck-streams :only (writer reader)])или даже лучше, укажите его в верхней части файла в определении пространства имен:
(ns com.me.project (:use [clojure.contrib.test-is :only (deftest is run-tests)]))
Ответ 4
Как уже упоминалось, большая разница заключается в том, что при (require 'foo)
вы ссылаетесь на имена в пространстве имен lib следующим образом: (foo/bar ...)
, если вы делаете (use 'foo)
, то они теперь находятся в вашем текущем пространстве имен (независимо от того, что может быть и при условии, что конфликтов нет), и вы можете назвать их как (bar ...)
.