2012-03-18 70 views
7

在Clojure命名空間中是否有可能從java.lang中排除類名?在Clojure命名空間中排除java.lang。*

我需要使用變量,如字節和字符串,這裏的類名的java.lang進入我的方式。

可能類似於(ns my-ns(:exclude java.lang))?

+1

的clojure.core命名空間取決於很多的東西java.lang中。*,所以我不知道這是即使可以重新定義這些類是個好主意。例如,'str','keyword','for',是使用'java.lang.String'類的函數和宏。 – 2012-03-18 12:48:26

+1

我認爲這不應該是一個問題,只要這些不是宏,並在運行時使用「字符串」。我也可以排除由其他函數使用的clojure.core函數,因爲它們在內部完全合格。所以使用String時,在內部使用java.lang.String時應該不成問題。 – 2012-03-18 13:10:15

+0

出於好奇,_why_你需要命名變量'Byte'和'String'嗎? – Gert 2012-03-18 19:46:28

回答

8

如果使用完全限定名稱,則沒有歧義。例如:

user=> (def user/Byte (java.lang.Byte/decode "0")) 
#'user/Byte 

你以這種方式定義字節之後,字節將解決您的定義沒有需要限定名稱

user=> Byte 
0 
1

我不知道確切的答案你的問題,但我的猜測是,你不能沒有修改的Clojure本身。下面是我的分析:

String符號在clojure/lang/Namespace.java實習作爲默認的映射(請參閱該類別,這在clojure/lang/RT.java類引用DEFAULT_MAPPINGSNamespace構造函數)的一部分。 Interning意味着名稱空間類的成員變量mappings中有一個鍵。這樣做的結果是,每命名String映射到String.class開始(見RT.java的Clojure中的1.4.0線77)。

ns宏,你可以這樣做:

(ns my-ns 
    (:refer-clojure :exclude [<mapping to exclude>])) 

但這一切確實是跳過實習生新符號的代碼(見的Clojure/core.clj線3770 Clojure中的1.4.0) ,所以它無法幫助您從命名空間映射中刪除String

最後,如果你嘗試的東西,如一個(defn String ...)重新定義映射String編譯器會抱怨,因爲String.class不是Var一個實例。有關詳細信息,請參閱clojure 1.4.0中的clojure/lang/Compiler.java行6797)。

1

這當然是可能的,如果你手動刪除在創建自己的內置映射到java.lang.String之前:

$ cake repl 
repl-1=> (def String 1) 
java.lang.Exception: Expecting var, but String is mapped to class java.lang.String (NO_SOURCE_FILE:1) 
repl-1=> (ns-unmap *ns* 'String) 
nil 
repl-1=> (def String 1) 
#'repl-1/String 
repl-1=> String 
1 

雖然我會迴應一些其他評論,名爲String的東西不太可能讓您的生活愉快/方便。