如果我有一个符号名称空间是别名,比如q/w,我怎么能找到它的实际名称空间,比如说actual.namespace/w?如何查找符号的完全限定名称空间?
我知道resolve
会给我完全合格的变种,但我不知道如何获得变种的名称空间。
我能做的最好的是:
(defn fqns [s] (str (get (ns-aliases *ns*) (symbol (namespace s)))))
肯定有一个简单的方法?
如果我有一个符号名称空间是别名,比如q/w,我怎么能找到它的实际名称空间,比如说actual.namespace/w?如何查找符号的完全限定名称空间?
我知道resolve
会给我完全合格的变种,但我不知道如何获得变种的名称空间。
我能做的最好的是:
(defn fqns [s] (str (get (ns-aliases *ns*) (symbol (namespace s)))))
肯定有一个简单的方法?
你可以得到一个符号的命名空间对象,如下图所示(如果你想纳秒为字符串的名称,然后就叫末STR):
(defn fqns [s] (->> (resolve s) meta :ns))
本身具有任何没有直接连接符号命名空间对象;它的命名空间部分只是一个实际的字符串。只有当它是resolve
d时,该字符串才被视为在其中查找Var的实际名称空间的名称。 (特别是,您可以创建一个符号foo/bar
,而不创建名称空间foo
或注册foo
作为命名空间的别名。)因此,您需要通过resolve
或自己完成部分工作。
在第一种情况下,你可以说(在最新版本的Clojure的;或者你可以跳过连字符标志着属性访问 - 而不是-ns
,使用ns
- 是向后兼容)
(.. (resolve s) -ns -name)
这将解析Var对象,然后从其ns
字段中提取对其名称空间的引用,最后从其name
字段中提取名称空间的符号名称。 (请注意,namespace
和name
功能是行不通的,因为瓦尔和命名空间不落实clojure.lang.Named
)
从问题文本的功能也没关系,但它会更好地提取从符号名命名空间 - (.-name (get ...))
- 通过使用str
而不是依赖名称空间的toString
表示。
您可能还需要添加clojure.lang.Var
和clojure.lang.Namespace
键入提示,以避免在通话中反映出来。 (如果你希望他们更快,或者如果您需要*warn-on-reflection*
扭捏别的性能和希望避免在这里没用的警告。)
如果要处理的命名空间不存在的可能性(和返回nil
在这种情况下,与平常的Clojure成语)保持:
(defn fqns
([s]
(fqns (.-name *ns*) s))
([ns s]
(some-> ns
find-ns
.-name
ns-aliases
(get (symbol (namespace s)))
.-name)))
或者用Clojure 1.4使用一些if-let
S和更早版本。