2013-04-18 43 views
3

如果我有一個符號名稱空間是別名,比如q/w,我怎麼能找到它的實際名稱空間,比如說actual.namespace/w?如何查找符號的完全限定名稱空間?

我知道resolve會給我完全合格的變種,但我不知道如何獲得變種的名稱空間。

我能做的最好的是:

(defn fqns [s] (str (get (ns-aliases *ns*) (symbol (namespace s))))) 

肯定有一個簡單的方法?

回答

7

你可以得到一個符號的命名空間對象,如下圖所示(如果你想納秒爲字符串的名稱,然後就叫末STR):

(defn fqns [s] (->> (resolve s) meta :ns)) 
2

本身具有任何沒有直接連接符號命名空間對象;它的命名空間部分只是一個實際的字符串。只有當它是resolve d時,該字符串才被視爲在其中查找Var的實際名稱空間的名稱。 (特別是,您可以創建一個符號foo/bar,而不創建名稱空間foo或註冊foo作爲命名空間的別名。)因此,您需要通過resolve或自己完成部分工作。

在第一種情況下,你可以說(在最新版本的Clojure的;或者你可以跳過連字符標誌着屬性訪問 - 而不是-ns,使用ns - 是向後兼容)

(.. (resolve s) -ns -name) 

這將解析Var對象,然後從其ns字段中提取對其名稱空間的引用,最後從其name字段中提取名稱空間的符號名稱。 (請注意,namespacename功能是行不通的,因爲瓦爾和命名空間不落實clojure.lang.Named

從問題文本的功能也沒關係,但它會更好地提取從符號名命名空間 - (.-name (get ...)) - 通過使用str而不是依賴名稱空間的toString表示。

您可能還需要添加clojure.lang.Varclojure.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和更早版本。

相關問題