2012-03-18 67 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的东西不太可能让您的生活愉快/方便。