Разница между использованием и требованием

Может ли кто-нибудь объяснить разницу между 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 ...).