這恐怕用例是豐富的思想,不是我的,但也許會感興趣:
語言本身使用此功能在def
形式(和很方便的宏包裝def
,包括defn
和defmacro
),因爲附加到命名創建的Vars符號的元數據將被轉移到Vars本身。它可以被編譯器和各種工具使用。
有人可能會指出defn
&有限公司可能會選擇一個屬性映射參數,它被合併到Vars元數據中,所以從用戶的角度來看,不需要在符號名稱上使用元數據。但是,Plain def
不會,並且內部defn
將擴展爲def
表單,其中元數據來自附加到Var名稱本身的屬性映射。 (爲了完整起見,在創建後可以在一個單獨的步驟中修改Var的元數據映射,但這不是defn
中發生的情況。)
所有這一切都不會被程序員隱藏,通過方式。相反,將元數據附加到符號「手工」在許多情況下比使用屬性映射更簡潔(可能甚至可以說更多的慣用)。 Clojure的自己的標準庫使用這種風格(我的意思是,自舉後) - 例如,既clojure.core
和clojure.string
定義瓦爾命名replace
,但只有後者被打上了返回值的類型(即String
):
;;; clojure.core
(defn replace
...)
;;; clojure.string
(defn ^String replace
...)
^String
此處轉換爲{:tag String}
,它在讀取時附加到符號replace
,稍後由編譯器使用(作爲類型提示)。其他用途包括將Vars標記爲私有,^:private
(在1.2中的Clojure 1.3,^{:private true}
中),將文檔字符串附加到用普通的def
創建的變量(1.2中唯一的方法; 1.3允許額外的文檔字符串參數,但^{:doc "..."}
仍在使用中)等。
同樣,在ClojureScript中,你可能有兩個函數名爲foo
,其中只有一個應該導出(當然,生活在不同的命名空間中)。在這種情況下,你會說
(defn ^:export foo ...)
在一個命名空間和
(defn foo ...)
在其他
; ^:export
在讀取時被翻譯爲^{:export true}
,這將被合併到符號foo
的出現的元數據中,然後由ClojureScript編譯器讀取並採取行動。
非原生的呢? – 2012-02-21 18:39:25