kullanım ve ihtiyaç arasındaki fark


155

Herkes hem doğrudan hem de makro olarak ve makroda kullanıldığında useve arasındaki farkı açıklayabilir mi?require:use:requirens


2
Ns makrosu ile ilgili olarak bkz. Stackoverflow.com/questions/10358149/… ; clojure 1.4 içinde kullanmanız önerilir: tercihe göre gerektirir: use
Korny

Yanıtlar:


101

requireyükler libs (zaten yüklü değil), useaynı artı ile onların ad alanlarına atıfta bulunur clojure.core/refer(böylece :excludevb ile kullanma olasılığını da elde edersiniz clojure.core/refer). Her ikisinin de nsdoğrudan yerine kullanılması önerilir .


3
Eğer lib foo'ya ihtiyacım varsa, foo'da bar kullanmak için her seferinde foo / bar yazmam gerekir, değil mi? Niçin bir lib'i ns olarak yüklemek istiyorsunuz ama sonra ns'ye göndermiyorsunuz? Sanırım çarpışmalar konusunda endişeleniyor olabilirsiniz ve onları uzlaştırmak zorunda kalmak istemezsiniz, değil mi?
Jegschemesch

12
çarpışmaları uzlaştırmak iyi bir nokta değildir ve daha genel olarak "ad alanları büyük bir fikirdir, onlardan daha fazlasına sahip olmalıyız" ("Python'un Zen'i" nden) yazan bir programlama stili vardır. "namespace foo kullanarak" kullanmamak; C ++ 'da, böylece kod okuyucular ve koruyucular "bu çubuk nereden geliyor" endişelenmek zorunda kalmayacak, ancak bunun yerine daha açık bir foo :: bar bakın. requir (vs use) bu "açık ad alanları" stilini destekler.
Alex Martelli

2
Alex iyi ama modası geçmiş bir cevap veriyor. @ Overthink aşağıda belirtildiği gibi, bu cevap verildikten sonra deyimsel clojure aşırı kullanım gerektirir. bkz. dev.clojure.org/jira/browse/CLJ-879
Phil Cooper

Bu kabul edilen ve en çok oylanan cevap olsa da eskidir ve modası geçmiş bir görüşü temsil eder. Daha iyi cevap şudur: @rzv: stackoverflow.com/a/16429572/172272
Didier A.

65

requireVe ile harici işlevleri dahil etmek deyimseldir refer. Ad alanı çakışmalarını önler, yalnızca gerçekten kullandığınız / ihtiyacınız olan işlevleri dahil edersiniz ve her işlevin konumunu açıkça bildirirsiniz:

(ns project.core
    (:require [ring.middleware.reload :refer [wrap-reload]]))

Bu işlevi kendi ad alanı ile ön ek olarak çağırmak zorunda değilsiniz:

(wrap-reload) ; works

Eğer kullanmazsanız refer, ad alanı ile ön ek yapmanız gerekir:

(ring.middleware.reload/wrap-reload) ; works if you don't use refer in your require

Seçerseniz useyerine, (hemen hemen) her zaman kullanmak only:

(ns project.core
    (:use [ring.middleware.reload :only [wrap-reload]]))

Aksi takdirde, her şeyi dahil edersiniz, hem gereksiz yere büyük bir işlem yapar hem de diğer programcılar için işlevlerin nerede yaşadığını bulması çok kafa karıştırıcıdır.

Ayrıca, bu blogu Clojure ad alanları hakkında daha fazla bilgi edinmek için bir kaynak olarak tavsiye ederim .


Sonunda (:use foo :only [bar])ve arasında herhangi bir fark olup olmadığını biliyor musunuz (:require foo :refer [bar])? Bunu yapmanın iki yolu var gibi görünüyor.
overthink

10
Görünüşe göre stackoverflow.com/a/10370672/69689 sorumu yanıtlıyor. Kısacası: (:require .. :refer ..)Aynı şeyi yapmanın etkili bir şekilde kullanımdan kaldırmanıza izin :useveren, bazı dezavantajları olan yeni bir yoludur .
overthink

İyi örnekler veriyoruz. Örnekleri seviyorum, bu çok mantıklıydı.
Astrid

35

Bir işlevi her çağırmak istediğinizde ad alanını hecelemenize gerek kalmadan emin olun, ancak ad alanı çakışmaları oluşturarak bir şeyler karıştırabilirsiniz. "Use" ve "requir" arasındaki iyi bir orta yol, gerçekte kullandığınız bir ad alanından işlevleri 'kullanmak'tır.

Örneğin:

 ('[clojure-particip.duck-streams: only (writer reader)]' i kullanın)
veya daha iyisi, ad alanı tanımında dosyanın üstünde belirtin:

(ns com.me.project
   (: [clojure.contrib.test-is: only (deftest çalışma testleri)] kullanın)))

3
(ns ...)Sözdizimini (pun) eklediğiniz için teşekkür ederiz ; Bunu arıyordum ama bulduğum tüm örnekler açıktı (use ...).
paul

1
GÜNCELLEME: Bu yöntem artık lehine(require '[namepase :refer [var-name1 var-name2]])
Arthur Ulfeldt

@ArthurUlfeldt Cevabınızı buna dahil etmek (pun) yapmak için cevabınızı güncellemek isteyebilirsiniz.
bfontaine

20

Daha önce de belirtildiği gibi, büyük fark, (require 'foo)lib'in ad alanındaki adlara şu şekilde atıfta bulunmanızdır: (foo/bar ...)eğer yaparsanız (use 'foo), şimdi mevcut ad alanınızdadır (ne olursa olsun ve çatışma yoksa) ve onlar gibi (bar ...).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.