Siehe auch stackoverflow.com/questions/10358149/… bezüglich des ns-Makros; In Clojure 1.4 wird empfohlen, Folgendes zu verwenden: Vorzugsweise benötigen: Verwenden
Korny
Antworten:
101
requireLädt Bibliotheken (die noch nicht geladen sind), usemacht dasselbe und verweist auf deren Namespaces mit clojure.core/refer(so dass Sie auch die Möglichkeit haben, :excludeetc wie mit zu verwenden clojure.core/refer). Beide werden nseher zur Verwendung als direkt empfohlen .
Wenn ich lib foo benötige, müsste ich jedes Mal foo / bar schreiben, um bar in foo zu verwenden, oder? Warum sollten Sie eine Bibliothek in ns laden wollen, sie dann aber nicht in die ns verweisen? Ich denke, Sie könnten sich Sorgen um Kollisionen machen und möchten sich nicht die Mühe machen, sie miteinander in Einklang zu bringen, oder?
Jegschemesch
12
Kollisionen nicht in Einklang bringen zu müssen, ist ein guter Punkt, und im Allgemeinen gibt es einen Programmierstil, der besagt, dass "Namespaces eine großartige Idee sind, wir sollten mehr davon haben" (aus "The Zen of Python") - also z. B. empfiehlt dieser Stil nicht "using namespace foo;" in C ++, damit sich Leser und Betreuer des Codes keine Sorgen machen müssen, "woher kommt diese Leiste", sondern stattdessen eine explizitere foo :: bar sehen. require (vs use) unterstützt diesen "expliziten Namespaces" -Stil.
Alex Martelli
2
Alex gibt eine gute, aber veraltete Antwort. Wie @overthink weiter unten ausführt, empfiehlt Clojure nach Erteilung dieser Antwort eine übermäßige Verwendung. siehe: dev.clojure.org/jira/browse/CLJ-879
Phil Cooper
Dies ist zwar die akzeptierte und am besten bewertete Antwort, sie ist jedoch alt und repräsentiert eine veraltete Ansicht. Die bessere Antwort ist die von @rzv: stackoverflow.com/a/16429572/172272
Didier A.
65
Es ist idiomatisch, externe Funktionen mit requireund einzuschließen refer. Sie vermeiden Namespace-Konflikte, schließen nur Funktionen ein, die Sie tatsächlich verwenden / benötigen, und Sie deklarieren explizit den Speicherort jeder Funktion:
Andernfalls schließen Sie alles ein, was es für andere Programmierer sowohl unnötig umfangreich als auch sehr verwirrend macht, herauszufinden, wo sich die Funktionen befinden.
Außerdem empfehle ich diesen Blog als Ressource, um mehr über Clojure-Namespaces zu erfahren.
Wissen Sie, ob es am Ende einen Unterschied zwischen (:use foo :only [bar])und gibt (:require foo :refer [bar])? Es scheint seltsam, zwei Möglichkeiten zu haben, dies zu tun.
Überdenken
10
Sieht aus wie stackoverflow.com/a/10370672/69689 beantwortet meine Frage. Kurz gesagt: Dies (:require .. :refer ..)ist eine neue Methode, um das Gleiche zu tun, mit der Sie effektiv ablehnen können :use, was einige Nachteile hat.
Überdenken
Gute Beispiele. Ich liebe Beispiele, das hat sehr viel Sinn gemacht.
Astrid
35
Verwenden Sie dies sicher, um es einfacher zu machen, indem Sie den Namespace nicht jedes Mal buchstabieren müssen, wenn Sie eine Funktion aufrufen möchten. Es kann jedoch auch zu Problemen führen, indem Namespace-Konflikte entstehen. Ein guter Mittelweg zwischen "use" und "require" besteht darin, nur die Funktionen aus einem Namespace zu "verwenden", den Sie tatsächlich verwenden.
zum Beispiel:
(benutze '[clojure-Contrib.duck-Streams: nur (Writer Reader)])
oder noch besser, geben Sie es oben in der Datei in der Namespace-Definition an:
(ns com.me.project
(: benutze [clojure.contrib.test-is: only (Geschicklichkeit ist Run-Tests)]))
Vielen Dank, dass Sie die (ns ...)Syntax (Wortspiel) eingefügt haben. Ich hatte danach gesucht, aber alle Beispiele, die ich fand, waren einfach (use ...).
Paul
1
UPDATE: Diese Methode wurde jetzt zugunsten von(require '[namepase :refer [var-name1 var-name2]])
Arthur Ulfeldt
@ArthurUlfeldt Möglicherweise möchten Sie Ihre Antwort aktualisieren, um dies einzuschließen (Wortspiel).
Bfontaine
20
Wie bereits erwähnt, besteht der große Unterschied darin, dass (require 'foo)Sie sich dann wie folgt auf Namen im Namespace der Bibliothek beziehen: (foo/bar ...)Wenn Sie dies tun (use 'foo), befinden sie sich jetzt in Ihrem aktuellen Namespace (was auch immer das sein mag und vorausgesetzt, es gibt keine Konflikte) und Sie können anrufen sie mögen (bar ...).
Antworten:
require
Lädt Bibliotheken (die noch nicht geladen sind),use
macht dasselbe und verweist auf deren Namespaces mitclojure.core/refer
(so dass Sie auch die Möglichkeit haben,:exclude
etc wie mit zu verwendenclojure.core/refer
). Beide werdenns
eher zur Verwendung als direkt empfohlen .quelle
Es ist idiomatisch, externe Funktionen mit
require
und einzuschließenrefer
. Sie vermeiden Namespace-Konflikte, schließen nur Funktionen ein, die Sie tatsächlich verwenden / benötigen, und Sie deklarieren explizit den Speicherort jeder Funktion:Ich muss diese Funktion nicht aufrufen, indem ich ihr den Namespace voranstelle:
Wenn Sie nicht verwenden
refer
, müssen Sie ihm den Namespace voranstellen:Wenn Sie
use
stattdessen wählen , verwenden Sie (so ziemlich) immeronly
:Andernfalls schließen Sie alles ein, was es für andere Programmierer sowohl unnötig umfangreich als auch sehr verwirrend macht, herauszufinden, wo sich die Funktionen befinden.
Außerdem empfehle ich diesen Blog als Ressource, um mehr über Clojure-Namespaces zu erfahren.
quelle
(:use foo :only [bar])
und gibt(:require foo :refer [bar])
? Es scheint seltsam, zwei Möglichkeiten zu haben, dies zu tun.(:require .. :refer ..)
ist eine neue Methode, um das Gleiche zu tun, mit der Sie effektiv ablehnen können:use
, was einige Nachteile hat.Verwenden Sie dies sicher, um es einfacher zu machen, indem Sie den Namespace nicht jedes Mal buchstabieren müssen, wenn Sie eine Funktion aufrufen möchten. Es kann jedoch auch zu Problemen führen, indem Namespace-Konflikte entstehen. Ein guter Mittelweg zwischen "use" und "require" besteht darin, nur die Funktionen aus einem Namespace zu "verwenden", den Sie tatsächlich verwenden.
zum Beispiel:
oder noch besser, geben Sie es oben in der Datei in der Namespace-Definition an:quelle
(ns ...)
Syntax (Wortspiel) eingefügt haben. Ich hatte danach gesucht, aber alle Beispiele, die ich fand, waren einfach(use ...)
.(require '[namepase :refer [var-name1 var-name2]])
Wie bereits erwähnt, besteht der große Unterschied darin, dass
(require 'foo)
Sie sich dann wie folgt auf Namen im Namespace der Bibliothek beziehen:(foo/bar ...)
Wenn Sie dies tun(use 'foo)
, befinden sie sich jetzt in Ihrem aktuellen Namespace (was auch immer das sein mag und vorausgesetzt, es gibt keine Konflikte) und Sie können anrufen sie mögen(bar ...)
.quelle