有没有可能在Clojure命名空间中排除java.lang类名?
我需要使用Byte和String这样的变量,但是java.lang类名阻碍了我的进展。
也许可以使用(ns my-ns (:exclude java.lang))之类的方式来实现?
有没有可能在Clojure命名空间中排除java.lang类名?
我需要使用Byte和String这样的变量,但是java.lang类名阻碍了我的进展。
也许可以使用(ns my-ns (:exclude java.lang))之类的方式来实现?
user=> (def user/Byte (java.lang.Byte/decode "0"))
#'user/Byte
如果您以这种方式定义了Byte,那么Byte将解析为您的定义而无需限定名称。
user=> Byte
0
如果您在创建自己的映射之前手动删除了对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的东西不太可能让你的生活变得愉快/方便。
我对你的问题没有明确的答案,但我的猜测是,如果不修改Clojure本身,你是做不到的。以下是我的分析:
String
符号作为默认映射的一部分在clojure/lang/Namespace.java
中被interned(请参见该类中的Namespace
构造函数,该函数引用clojure/lang/RT.java
类中的DEFAULT_MAPPINGS
)。Interning意味着,在Namespace类的成员变量中有一个键。这意味着每个命名空间都从String
映射到String.class
(请参见clojure 1.4.0中RT.java的第77行)。
在ns
宏中,您可以执行以下操作:
(ns my-ns
(:refer-clojure :exclude [<mapping to exclude>]))
但是这只是跳过了内部新符号的代码(请参见clojure 1.4.0中clojure/core.clj的第3770行),因此它无法帮助您从命名空间映射中删除String
。
最后,如果您尝试使用类似于(defn String ...)
的东西重新定义String
的映射,则编译器会抱怨,因为String.class
不是Var
的实例。有关详细信息,请参见clojure 1.4.0中clojure/lang/Compiler.java的第6797行)。
str
、keyword
、for
是使用java.lang.String
类的函数和宏。 - Brian CooleyByte
和String
? - Gert