різниця між використанням та потребою


155

Може хто - небудь пояснити різницю між useі require, як при використанні безпосередньо і , як :useі :requireв nsмакро?


2
Дивіться також stackoverflow.com/questions/10358149/… щодо макросу ns; в clojure 1.4 пропонується використовувати: вимагати надати перевагу: використовувати
— Корній

Відповіді:


101

requireвантажі ЛІЕС (які ще не завантажені), useробить те ж саме , плюс це відноситься до їх просторів імен з clojure.core/refer(так що ви також отримуєте можливість використання і :excludeт.д. , як з clojure.core/refer). Обидва рекомендується використовувати, nsа не безпосередньо.


3
Якщо мені потрібен lib foo, то для використання bar in foo я повинен писати foo / bar щоразу, правда? Чому ви хочете завантажити ліб в ns, але потім не пересилати його в ns? Я думаю, що ви можете турбуватися про зіткнення, і ви не хочете турбуватися про необхідність їх узгодження, правда?
— Джегшемеш

12
не потрібно узгоджувати зіткнення - це сприятливий момент, і в цілому існує стиль програмування, який говорить, що "простори імен - це чудова ідея, ми повинні їх мати більше" (від "Дзен Пітона") - так, наприклад, цей стиль рекомендує не використовується "використання foo простору імен;" в C ++, так що читачам та обслуговуючим кодам не доведеться турбуватися "звідки береться ця панель", а побачити більш чіткий foo :: bar. вимагає (проти використання) підтримує цей стиль "явних просторів імен".
— Алекс Мартеллі

2
Олексій дає хорошу, але застарілу відповідь. Як вказує @overthink нижче, після даної відповіді ідіоматична клоджура рекомендує вимагати надмірного використання. дивіться: dev.clojure.org/jira/browse/CLJ-879
— Phil Cooper

Хоча це прийнята і найбільш голосована відповідь, вона стара і являє собою застарілий вигляд. Кращою відповіддю є те , що з @rzv: stackoverflow.com/a/16429572/172272
— Didier А.

65

Ідіоматично включати зовнішні функції за допомогою 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.


Чи знаєте ви, чи є різниця в кінці між (:use foo :only [bar])і (:require foo :refer [bar])? Здається, дивним є два способи зробити це.
— передумати

10
Схоже, stackoverflow.com/a/10370672/69689 відповідає на моє запитання. Коротше кажучи: (:require .. :refer ..)це новий спосіб зробити те саме, що дозволяє ефективно застаріти :use, що має деякі недоліки.
— передумати

Добре наводить приклади. Я люблю приклади, це мало багато сенсу.
— Астрід

35

Переконайтеся, що це полегшує ситуацію, не вимагаючи, щоб ви прописували простір імен кожного разу, коли ви хочете викликати функцію, хоча це також може створювати безлад, створюючи конфлікти у просторі імен. Хорошим середнім середовищем між "використання" та "вимагати" є лише "використання" функцій з простору імен, які ви фактично використовуєте.

наприклад:

 (використовуйте '[clojure-contrib.duck-потоки: тільки (читач читачів)])
а ще краще, вкажіть його у верхній частині файлу у визначенні простору імен:

(ns com.me.project
   (: використовуйте [clojure.contrib.test-is: only (deftest is run-testing)]))

3
Дякую за включення (каламбур) (ns ...)синтаксису; Я шукав це, але всі знайдені нами приклади були зрозумілими (use ...).
— Павло

1
ОНОВЛЕННЯ: цей метод застарів зараз на користь(require '[namepase :refer [var-name1 var-name2]])
— Артур Ульфельт

@ArthurUlfeldt Можливо, ви захочете оновити свою відповідь, щоб включити (каламбур) це.
— bfontaine

20

Як вже згадувалося, велика різниця полягає в тому, що з (require 'foo), потім ви посилаєтесь на імена в просторі імен lib так: (foo/bar ...)якщо ви це зробите, (use 'foo)вони тепер знаходяться у вашому поточному просторі імен (що б там не було, і за умови, що немає конфліктів), і ви можете зателефонувати їм подобається (bar ...).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.