前言

?動(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

  1. Symbol

  2. Var

  3. Collections(List,Map,Vector,Set)

  4. Record

  5. 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)互勉!
??Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

http://www.cnblogs.com/fsjohnhuang/p/7203927.html