如果我有一個符號名稱空間是別名,比如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和更早版本。