(cljs/run-at (JSVM. :all) "Metadata就这样哦")
2017-07-19 09:14
459 查看
前言
动态类型语言,少了静态类型语言必须声明变量类型的累赘,但也缺失了编译时类型检查和编译时优化的好处。cljs虽然作为动态类型语言,但其提供Metadata让我们在必要的时候可选择地补充类型提示,以便提高代码可读性和供编译器优化使用。除了上述以外,Metadata还让我们在不影响对象本质的前提下,附加额外信息增强元编程能力。Metadata附加的目标
首先要明确一点的是,Metadata不是任何对象/值都拥有的。只有如下的对象才可附加MetadataSymbol
Var
Collections(List,Map,Vector,Set)
Record
Type
meta
读取Metadata
通过meta我们可以获取对象的Metadata,若没有则返回
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,显然后者是没有Metadata的。
示例2:获取Symbol的Metadata
(def a (with-meta 'a {:something "test"})) (meta a) ;;=> {:something "test"}
通过
with-meta我们可以获取附加了metadata的symbol
'a(注意作为入参的symbol
'a不会受到影响)。
with-meta
后期追加Metadata
上面我们已经看到with-meta的使用示例了,下面我们再看看具体的函数签名吧。
;; Returns an object of the same type and value as obj, with map m as its metadata. (with-meta obj m)
值得注意的是,
with-meta会的返回值才会附加上metadata,而入参obj不会附加上metadata。因此需要用绑定来保存结果,以便后续使用。
(def a (with-meta obj m))
定义时附加Metadata
除了with-meta后期追加外,很多时候我们是在定义时就已经可以明确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
有时我们只想定义一两个metadata,完整写法显然有些累赘,那么我们就可以采用metadata reader的写法,小清新一下。(def ^:dynamic ^"test" a 1) ;;等价于(def ^{:dynamic true, :tag "test"} a 1)
缩写是有限制,所以只能表达如下metadata
^:foo ;;=> ^{:foo true} ^"foo";;=> ^{:tag "foo"} ^foo ;;=> ^{:tag <value of foo>}
&esmp;至于其它metadata则还是要使用完整写法处理。
内置的metadata
:dynamic ;; Boolean, 指定Var为动态绑定 :private ;; Boolean, 指定该Symbol的访问控制为私有,默认为public :doc ;; String, 设置document string :test ;; Function,不带入参的函数,单元测试函数 :tag ;; Class,指定Symbol所指向的Var的数据类型
另外编译器会自动附加一下信息到Var上。
:file ;; String :line ;; Int :name ;; Symbol :ns ;; Symbol :macro ;; Boolean,true表示是macro :arglists ;; List<Vector>,每个Vector表示一个函数签名
总结
今天就写到这里,下次继续^^尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/7203927.html ^^肥仔John
相关文章推荐
- (cljs/run-at (JSVM. :all) "一起实现柯里化")
- (cljs/run-at (JSVM. :all) "细说函数")
- (cljs/run-at (JSVM. :all) "一次说白DataType、Record和Protocol")
- (cljs/run-at (JSVM. :browser) "简单类型可不简单啊~")
- (cljs/run-at (JSVM. :browser) "命名空间就这么简单")
- (cljs/run-at (->JSVM :browser) "语言基础")
- (cljs/run-at (JSVM. :browser) "搭建刚好可用的开发环境!")
- ndk-build all Error: Cannot run program "ndk-build": Launching failed
- 【续集】塞翁失马,焉知非福:由 Styles.Render 所引发 runAllManagedModulesForAllRequests="true" 的思考
- WebView中删除JS中confirm框上的The page at "file".....
- <table runat="server"> 元素要在增加行TR的TD中内嵌
- runAllManagedModulesForAllRequests="true" 的思考
- MTK模拟器Could not run "cl.exe"错误
- <modules runAllManagedModulesForAllRequests="true" />(转1)
- 塞翁失马,焉知非福:由 Styles.Render 所引发 runAllManagedModulesForAllRequests="true" 的思考
- 执行docker ps命令,出现 "Cannot connect to the Docker daemon at unix:///var/run/docker.sock. ..."问题
- 移动端压缩图片。上传获取图片并压缩。lrz.all.bundle.js插件。 accept="image/*"加载慢的问题
- count failed: not master{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" } at src/mongo/shell/query.js:191在SECONDARY节点无法show dbs
- Node.Js + express, run "hello world " in windows 8.1
- js实现"replaceAll"