前言
?動(dòng)態(tài)類型語(yǔ)言,少了靜態(tài)類型語(yǔ)言必須聲明變量類型的累贅,但也缺失了編譯時(shí)類型檢查和編譯時(shí)優(yōu)化的好處。cljs雖然作為動(dòng)態(tài)類型語(yǔ)言,但其提供Metadata讓我們?cè)诒匾臅r(shí)候可選擇地補(bǔ)充類型提示,以便提高代碼可讀性和供編譯器優(yōu)化使用。除了上述以外,Metadata還讓我們?cè)诓挥绊憣?duì)象本質(zhì)的前提下,附加額外信息增強(qiáng)元編程能力。
Metadata附加的目標(biāo)
?首先要明確一點(diǎn)的是,Metadata不是任何對(duì)象/值都擁有的。只有如下的對(duì)象才可附加Metadata
Symbol
Var
Collections(List,Map,Vector,Set)
Record
Type
meta
讀取Metadata
?通過(guò)meta
我們可以獲取對(duì)象的Metadata,若沒(méi)有則返回nil
。
示例1:獲取Var的Metadata
(def a 1)(meta #'a);;=> {:ns cljs.user, :name a, :file "<cljs repl>", :end-column 7, :source "a", :column 1, :line 1, :end-line 1, :arglists (), :doc nil, :test nil}
?上述示例1中是(meta #'a)
而不是(meta a)
,前者是獲取Var的Metadata,而后者是獲取值1的Metadata,顯然后者是沒(méi)有Metadata的。
示例2:獲取Symbol的Metadata
(def a (with-meta 'a {:something "test"})) (meta a);;=> {:something "test"}
?通過(guò)with-meta
我們可以獲取附加了metadata的symbol'a
(注意作為入?yún)⒌膕ymbol'a
不會(huì)受到影響)。
with-meta
后期追加Metadata
?上面我們已經(jīng)看到with-meta
的使用示例了,下面我們?cè)倏纯淳唧w的函數(shù)簽名吧。
;; Returns an object of the same type and value as obj, with map m as its metadata.(with-meta obj m)
?值得注意的是,with-meta
會(huì)的返回值才會(huì)附加上metadata,而入?yún)bj不會(huì)附加上metadata。因此需要用綁定來(lái)保存結(jié)果,以便后續(xù)使用。
(def a (with-meta obj m))
定義時(shí)附加Metadata
?除了with-meta
后期追加外,很多時(shí)候我們是在定義時(shí)就已經(jīng)可以明確metadata的了,那么可以兩種形式定義metadata。
完整寫法
;; 定義Var的metadata(def ^{:dynamic true, :tag "test"} a 1);; 讀取metadata(meta #'a);; 定義Map的metadata(def b ^{:something "test"} {:name 1});; 讀取metadata(meta b)
縮寫——Metadata Reader
?有時(shí)我們只想定義一兩個(gè)metadata,完整寫法顯然有些累贅,那么我們就可以采用metadata reader的寫法,小清新一下。
(def ^:dynamic ^"test" a 1) ;;等價(jià)于(def ^{:dynamic true, :tag "test"} a 1)
?縮寫是有限制,所以只能表達(dá)如下metadata
^:foo ;;=> ^{:foo true} ^"foo";;=> ^{:tag "foo"} ^foo ;;=> ^{:tag <value of foo>}
&esmp;至于其它metadata則還是要使用完整寫法處理。
內(nèi)置的metadata
:dynamic ;; Boolean, 指定Var為動(dòng)態(tài)綁定 :private ;; Boolean, 指定該Symbol的訪問(wèn)控制為私有,默認(rèn)為public:doc ;; String, 設(shè)置document string:test ;; Function,不帶入?yún)⒌暮瘮?shù),單元測(cè)試函數(shù) :tag ;; Class,指定Symbol所指向的Var的數(shù)據(jù)類型
另外編譯器會(huì)自動(dòng)附加一下信息到Var上。
:file ;; String:line ;; Int:name ;; Symbol:ns ;; Symbol:macro ;; Boolean,true表示是macro:arglists ;; List<Vector>,每個(gè)Vector表示一個(gè)函數(shù)簽名
總結(jié)
?今天就寫到這里,下次繼續(xù)^^
尊重原創(chuàng),轉(zhuǎn)載請(qǐng)注明來(lái)自:http://www.cnblogs.com/fsjohnhuang/p/7203927.html ^^肥仔John
如果您覺(jué)得本文的內(nèi)容有趣就掃一下吧!捐贈(zèng)互勉!
??
http://www.cnblogs.com/fsjohnhuang/p/7203927.html