在Clojure命名空间中排除java.lang。*

时间:2012-03-18 12:28:44

标签: java clojure namespaces

是否有可能在Clojure名称空间中从java.lang中排除类名?

我需要使用像Byte和String这样的变量,这里java.lang类名就会出现。

可能是(ns my-ns(:exclude java.lang))?

3 个答案:

答案 0 :(得分:9)

如果您使用完全限定名称,则不存在歧义。例如:

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

在您以这种方式定义字节后,字节将解析为您的定义,而不需要限定名称

user=> Byte
0

答案 1 :(得分:1)

我不知道你的问题的确切答案,但我的有根据的猜测是你不能不修改clojure本身。这是我的分析:

String符号作为默认映射的一部分在clojure/lang/Namespace.java中实现(请参阅该类中的Namespace构造函数,该构造函数引用DEFAULT_MAPPINGS中的clojure/lang/RT.java })。实习意味着Namespace类的成员变量mappings中有一个键。这样做的结果是每个命名空间都以映射到String的{​​{1}}开头(参见clojure 1.4.0中RT.java的第77行)。

String.class宏中,您可以执行以下操作:

ns

但所有这一切都是跳过实现新符号的代码(参见clojure 1.4.0中clojure / core.clj的第3770行),因此它无法帮助您从(ns my-ns (:refer-clojure :exclude [<mapping to exclude>])) 中删除String命名空间映射。

最后,如果您尝试使用类似String的内容重新定义(defn String ...)的映射,则编译器会抱怨,因为String.class不是Var的实例。有关详细信息,请参见clojure 1.4.0中clojure / lang / Compiler.java的第6797行。

答案 2 :(得分: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的东西不太可能让你的生活愉快/方便。