Lihat juga stackoverflow.com/questions/10358149/… sehubungan dengan ns macro; di clojure 1.4 disarankan Anda menggunakan: mengharuskan dengan preferensi untuk: menggunakan
Korny
Jawaban:
101
requireload libs (yang belum dimuat), usemelakukan plus yang sama mengacu pada namespace mereka dengan clojure.core/refer(jadi Anda juga mendapatkan kemungkinan menggunakan :excludedll suka dengan clojure.core/refer). Keduanya direkomendasikan untuk digunakan nsdaripada langsung.
Jika saya memerlukan lib foo, maka untuk menggunakan bar di foo, saya harus menulis foo / bar setiap waktu, bukan? Mengapa Anda ingin memuat lib dalam ns tetapi kemudian tidak merujuknya ke ns? Saya kira Anda mungkin khawatir tentang tabrakan, dan Anda tidak ingin repot harus mendamaikan mereka, kan?
Jegschemesch
12
tidak harus mendamaikan tabrakan adalah poin yang baik, dan lebih umum ada gaya pemrograman yang mengatakan "namespaces adalah ide besar yang membunyikan klakson, kita harus memiliki lebih dari itu" (dari "The Zen of Python") - jadi misalnya gaya itu merekomendasikan tidak menggunakan "using namespace foo;" di C ++, sehingga pembaca dan pengelola kode tidak perlu khawatir "dari mana bilah ini berasal" tetapi lihat foo :: bar yang lebih eksplisit sebagai gantinya. mengharuskan (vs digunakan) mendukung gaya "ruang nama eksplisit" ini.
Alex Martelli
2
Alex memberikan jawaban yang bagus tapi ketinggalan jaman. Seperti yang ditunjukkan oleh @overthink di bawah ini, setelah jawaban ini diberikan, clojure idiomatis merekomendasikan penggunaan yang berlebihan. lihat: dev.clojure.org/jira/browse/CLJ-879
Phil Cooper
Meskipun ini adalah jawaban yang diterima dan paling banyak dipilih, itu sudah tua dan mewakili pandangan yang sudah ketinggalan zaman. Jawaban yang lebih baik adalah dari @rzv: stackoverflow.com/a/16429572/172272
Didier A.
65
Adalah idiomatis untuk memasukkan fungsi eksternal dengan requiredan refer. Anda menghindari konflik namespace, Anda hanya menyertakan fungsi yang sebenarnya Anda gunakan / butuhkan, dan Anda secara eksplisit menyatakan lokasi masing-masing fungsi:
Kalau tidak, Anda memasukkan semuanya, menjadikannya sebuah operasi besar yang tidak perlu dan sangat membingungkan bagi programmer lain untuk menemukan di mana fungsinya.
Juga, saya sangat merekomendasikan blog ini sebagai sumber untuk mempelajari lebih lanjut tentang ruang nama Clojure.
Apakah Anda tahu jika ada perbedaan pada akhirnya antara (:use foo :only [bar])dan (:require foo :refer [bar])? Tampaknya aneh memiliki dua cara untuk melakukan ini.
terlalu banyak berpikir
10
Sepertinya stackoverflow.com/a/10370672/69689 menjawab pertanyaan saya. Singkatnya: (:require .. :refer ..)adalah cara baru untuk melakukan hal yang sama yang memungkinkan Anda untuk secara efektif terdepresiasi :use, yang memiliki beberapa kelemahan.
overthink
Berikan contoh yang bagus. Saya suka contoh, ini sangat masuk akal.
Astrid
35
Penggunaan tentu membuat lebih mudah dengan tidak mengharuskan Anda untuk mengeja namespace setiap kali Anda ingin memanggil fungsi meskipun itu juga dapat membuat kekacauan dengan menciptakan konflik namespace. Jalan tengah yang baik antara "gunakan" dan "perlu" adalah dengan hanya 'menggunakan' fungsi-fungsi dari namespace yang sebenarnya Anda gunakan.
misalnya:
(gunakan '[clojure-contrib.duck-stream: only (writer reader)])
atau bahkan lebih baik, tentukan di bagian atas file dalam definisi namespace:
(proyek ns com.me.
(: gunakan [clojure.contrib.test-is: only (deftest run-tes)]))
Terima kasih telah memasukkan (pun) (ns ...)sintaksis; Saya telah mencari-cari itu tetapi semua contoh yang saya temukan jelas (use ...).
paul
1
UPDATE: metode ini telah usang sekarang mendukung(require '[namepase :refer [var-name1 var-name2]])
Arthur Ulfeldt
@ArthurUlfeldt Anda mungkin ingin memperbarui jawaban Anda untuk memasukkan (pun) ini.
bfontaine
20
Seperti telah disebutkan perbedaan besar adalah dengan (require 'foo), Anda kemudian merujuk nama-nama di namespace lib seperti: (foo/bar ...)jika Anda melakukannya (use 'foo)maka mereka sekarang di namespace Anda saat ini (apa pun yang mungkin dan asalkan tidak ada konflik) dan Anda dapat memanggil mereka suka (bar ...).
Jawaban:
require
load libs (yang belum dimuat),use
melakukan plus yang sama mengacu pada namespace mereka denganclojure.core/refer
(jadi Anda juga mendapatkan kemungkinan menggunakan:exclude
dll suka denganclojure.core/refer
). Keduanya direkomendasikan untuk digunakanns
daripada langsung.sumber
Adalah idiomatis untuk memasukkan fungsi eksternal dengan
require
danrefer
. Anda menghindari konflik namespace, Anda hanya menyertakan fungsi yang sebenarnya Anda gunakan / butuhkan, dan Anda secara eksplisit menyatakan lokasi masing-masing fungsi:Saya tidak harus menjalankan fungsi ini dengan mengawalinya dengan namespace-nya:
Jika Anda tidak menggunakannya,
refer
Anda harus membuatnya awalan dengan namespace:Jika Anda memilih
use
sebagai gantinya, (cukup banyak) selalu menggunakanonly
:Kalau tidak, Anda memasukkan semuanya, menjadikannya sebuah operasi besar yang tidak perlu dan sangat membingungkan bagi programmer lain untuk menemukan di mana fungsinya.
Juga, saya sangat merekomendasikan blog ini sebagai sumber untuk mempelajari lebih lanjut tentang ruang nama Clojure.
sumber
(:use foo :only [bar])
dan(:require foo :refer [bar])
? Tampaknya aneh memiliki dua cara untuk melakukan ini.(:require .. :refer ..)
adalah cara baru untuk melakukan hal yang sama yang memungkinkan Anda untuk secara efektif terdepresiasi:use
, yang memiliki beberapa kelemahan.Penggunaan tentu membuat lebih mudah dengan tidak mengharuskan Anda untuk mengeja namespace setiap kali Anda ingin memanggil fungsi meskipun itu juga dapat membuat kekacauan dengan menciptakan konflik namespace. Jalan tengah yang baik antara "gunakan" dan "perlu" adalah dengan hanya 'menggunakan' fungsi-fungsi dari namespace yang sebenarnya Anda gunakan.
misalnya:
atau bahkan lebih baik, tentukan di bagian atas file dalam definisi namespace:sumber
(ns ...)
sintaksis; Saya telah mencari-cari itu tetapi semua contoh yang saya temukan jelas(use ...)
.(require '[namepase :refer [var-name1 var-name2]])
Seperti telah disebutkan perbedaan besar adalah dengan
(require 'foo)
, Anda kemudian merujuk nama-nama di namespace lib seperti:(foo/bar ...)
jika Anda melakukannya(use 'foo)
maka mereka sekarang di namespace Anda saat ini (apa pun yang mungkin dan asalkan tidak ada konflik) dan Anda dapat memanggil mereka suka(bar ...)
.sumber