sự khác biệt giữa sử dụng và yêu cầu


155

Bất cứ ai cũng có thể giải thích sự khác biệt giữa userequire, cả khi được sử dụng trực tiếp và như :use:requiretrong nsmacro?


2
Xem thêm stackoverflow.com/questions/10358149/ về liên quan đến macro ns; trong clojure 1.4, bạn nên sử dụng: yêu cầu theo sở thích: sử dụng
Korny

Câu trả lời:


101

requiretải libs (chưa được tải), usethực hiện tương tự cộng với nó đề cập đến không gian tên của chúng với clojure.core/refer(vì vậy bạn cũng có thể sử dụng :excludevv như với clojure.core/refer). Cả hai đều được khuyến nghị sử dụng nsthay vì trực tiếp.


3
Nếu tôi yêu cầu lib foo, thì để sử dụng thanh trong foo, tôi sẽ phải viết foo / bar mỗi lần, phải không? Tại sao bạn muốn tải một lib trong ns nhưng sau đó không giới thiệu nó vào ns? Tôi đoán bạn có thể lo lắng về sự va chạm, và bạn không muốn phải giải quyết chúng, phải không?
Jegschemech

12
không phải điều hòa các va chạm là một điểm tốt, và nói chung là có một phong cách lập trình nói rằng "không gian tên là một ý tưởng tuyệt vời, chúng ta nên có nhiều hơn" (từ "Zen of Python") - vì vậy, ví dụ như phong cách đó khuyến nghị không sử dụng "sử dụng không gian tên foo;" trong C ++, để người đọc và người duy trì mã sẽ không phải lo lắng "thanh này đến từ đâu" mà thay vào đó hãy xem một thanh foo :: rõ ràng hơn. yêu cầu (so với sử dụng) hỗ trợ kiểu "không gian tên rõ ràng" này.
Alex Martelli

2
Alex đưa ra một câu trả lời tốt nhưng lỗi thời. Như @overthink chỉ ra dưới đây, sau khi câu trả lời này được đưa ra thành ngữ clojure khuyến nghị yêu cầu sử dụng quá mức. xem: dev.clojure.org/jira/browse/CLJ-879
Phil Cooper

Mặc dù đây là câu trả lời được chấp nhận và được bình chọn nhiều nhất, nhưng nó đã cũ và thể hiện một quan điểm lỗi thời. Câu trả lời tốt hơn là từ @rzv: stackoverflow.com/a/16429572/172272
Didier A.

65

Nó là thành ngữ để bao gồm các chức năng bên ngoài với requirerefer. Bạn tránh xung đột không gian tên, bạn chỉ bao gồm các chức năng bạn thực sự sử dụng / cần và bạn tuyên bố rõ ràng từng vị trí của chức năng:

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

Tôi không phải gọi hàm này bằng cách thêm tiền tố vào không gian tên của nó:

(wrap-reload) ; works

Nếu bạn không sử dụng, referbạn cần phải thêm tiền tố vào không gian tên:

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

Nếu bạn chọn usethay thế, (khá nhiều) luôn sử dụng only:

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

Mặt khác, bạn bao gồm tất cả mọi thứ, làm cho nó trở thành một hoạt động lớn không cần thiết và rất khó hiểu cho các lập trình viên khác để tìm nơi các chức năng sống.

Ngoài ra, tôi đánh giá cao blog này như một tài nguyên để tìm hiểu thêm về không gian tên Clojure.


Bạn có biết nếu có sự khác biệt nào ở cuối (:use foo :only [bar])và giữa (:require foo :refer [bar])không? Có vẻ kỳ quặc để có hai cách để làm điều này.
lật đổ

10
Hình như stackoverflow.com/a/10370672/69689 trả lời câu hỏi của tôi. Tóm lại: (:require .. :refer ..)là một cách mới để làm điều tương tự cho phép bạn phản đối một cách hiệu quả :use, có một số nhược điểm.
lật đổ

Ví dụ tốt cho. Tôi yêu các ví dụ, điều này rất có ý nghĩa.
Astrid

35

Sử dụng chắc chắn sẽ làm cho nó dễ dàng hơn bằng cách không yêu cầu bạn đánh vần không gian tên mỗi khi bạn muốn gọi một hàm mặc dù nó cũng có thể tạo ra sự lộn xộn của mọi thứ bằng cách tạo xung đột không gian tên. Một nền tảng tốt giữa "sử dụng" và "yêu cầu" là chỉ "sử dụng" các chức năng từ một không gian tên mà bạn thực sự sử dụng.

ví dụ:

 (sử dụng '[clojure-contrib.duck-stream: only (người đọc nhà văn)])
hoặc thậm chí tốt hơn, chỉ định nó ở đầu tệp trong định nghĩa không gian tên:

(ns com.me.project
   (: sử dụng [clojure.contrib.test-is: only (deftest là run-tests)]))

3
Cảm ơn đã bao gồm (chơi chữ) (ns ...)cú pháp; Tôi đã tìm kiếm điều đó nhưng tất cả các ví dụ tôi tìm thấy đều đơn giản (use ...).
paul

1
CẬP NHẬT: phương pháp này hiện đã bị lỗi thời(require '[namepase :refer [var-name1 var-name2]])
Arthur Ulfeldt

@ArthurUlfeldt Bạn có thể muốn cập nhật câu trả lời của mình để bao gồm (chơi chữ) này.
bfontaine

20

Như đã đề cập, sự khác biệt lớn là với (require 'foo), sau đó bạn tham khảo các tên trong không gian tên của lib như vậy: (foo/bar ...)nếu bạn làm như vậy (use 'foo)thì bây giờ chúng đang ở trong không gian tên hiện tại của bạn (bất cứ điều gì có thể và miễn là không có xung đột) và bạn có thể gọi họ thích (bar ...).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.