2010-08-04 43 views
27

我最近開始學習Clojure,並且在命名空間中纏繞我的頭有點困難。正如Clojure的創始人所說,新人往往很難正確理解概念。我不清楚(use ...)(require ...)之間的區別。例如,在REPL中玩弄,如果我說(use 'clojure.contrib.str-utils2),我會收到有關clojure.core命名空間中的函數的警告,它們將被clojure.contrib.str-utils2中的函數替換,但在使用(require 'clojure.contrib.str-utils2)時不會發生。我不確定我會一直想要替換clojure.core中的內容,那麼有人可以指出一些在Clojure中導入外部內容和管理名稱空間的最佳實踐嗎?Clojure在使用和需求之間的區別

哦,還有,我應該什麼時候使用:use:require?只在(ns ....)內?

在此先感謝。

+0

[使用和需求之間的差異]的可能重複(http://stackoverflow.com/questions/871997/difference-between-use-and-require) – 2013-02-26 15:53:22

回答

42

答案就在文檔字符串:

user> (doc use) 
------------------------- 
clojure.core/use 
([& args]) 
    Like 'require, but also refers to each lib's namespace using 
    clojure.core/refer. Use :use in the ns macro in preference to calling 
    this directly. 

    'use accepts additional options in libspecs: :exclude, :only, :rename. 
    The arguments and semantics for :exclude, :only, and :rename are the same 
    as those documented for clojure.core/refer. 
nil 

和長一個要求:

user> (doc require) 
------------------------- 
clojure.core/require 
([& args]) 
    Loads libs, skipping any that are already loaded. Each argument is 
    either a libspec that identifies a lib, a prefix list that identifies 
    multiple libs whose names share a common prefix, or a flag that modifies 
    how all the identified libs are loaded. Use :require in the ns macro 
    in preference to calling this directly. 

    Libs 

    A 'lib' is a named set of resources in classpath whose contents define a 
    library of Clojure code. Lib names are symbols and each lib is associated 
    with a Clojure namespace and a Java package that share its name. A lib's 
    name also locates its root directory within classpath using Java's 
    package name to classpath-relative path mapping. All resources in a lib 
    should be contained in the directory structure under its root directory. 
    All definitions a lib makes should be in its associated namespace. 

    'require loads a lib by loading its root resource. The root resource path 
    is derived from the lib name in the following manner: 
    Consider a lib named by the symbol 'x.y.z; it has the root directory 
    <classpath>/x/y/, and its root resource is <classpath>/x/y/z.clj. The root 
    resource should contain code to create the lib's namespace (usually by using 
    the ns macro) and load any additional lib resources. 

    Libspecs 

    A libspec is a lib name or a vector containing a lib name followed by 
    options expressed as sequential keywords and arguments. 

    Recognized options: :as 
    :as takes a symbol as its argument and makes that symbol an alias to the 
    lib's namespace in the current namespace. 

    Prefix Lists 

    It's common for Clojure code to depend on several libs whose names have 
    the same prefix. When specifying libs, prefix lists can be used to reduce 
    repetition. A prefix list contains the shared prefix followed by libspecs 
    with the shared prefix removed from the lib names. After removing the 
    prefix, the names that remain must not contain any periods. 

    Flags 

    A flag is a keyword. 
    Recognized flags: :reload, :reload-all, :verbose 
    :reload forces loading of all the identified libs even if they are 
    already loaded 
    :reload-all implies :reload and also forces loading of all libs that the 
    identified libs directly or indirectly load via require or use 
    :verbose triggers printing information about each load, alias, and refer 

    Example: 

    The following would load the libraries clojure.zip and clojure.set 
    abbreviated as 's'. 

    (require '(clojure zip [set :as s])) 
nil 

他們都做同樣的事情,但use去額外的步驟,並創建映射在當前命名空間的require'd命名空間中。這樣,而不是做some.namespace/name你只是指它作爲name。雖然這有時很方便,但最好使用require或選擇所需的各個變量,而不是拉入整個名稱空間。否則,您可能會遇到影子問題(其中一個var優先於另一個同名)。

如果你不想使用要求,但你知道你想要的名稱空間的什麼瓦爾,你可以這樣做:

(ns whatever 
    (:use [some.namespace :only [vars you want]])) 

如果你不知道哪個瓦爾你會需要,或者如果你需要很多,最好使用require。即使您需要,也不一定要輸入完全限定的名稱。你可以這樣做:

(ns whatever 
    (:require [some.namespace :as sn])) 

,然後你可以使用瓦爾從some.namespace像這樣:(sn/somefunction arg1 arg2)

並回答你的最後一個問題:儘量只使用:需要和:(納秒內使用...)。這樣更清潔。 (ns ..)之外不要userequire,除非你有一個很好的理由。

相關問題