(cljs/run-at (JSVM. :all) "Metadata就这样哦")
前言
动态类型语言,少了静态类型语言必须声明变量类型的累赘,但也缺失了编译时类型检查和编译时优化的好处。cljs虽然作为动态类型语言,但其提供Metadata让我们在必要的时候可选择地补充类型提示,以便提高代码可读性和供编译器优化使用。除了上述以外,Metadata还让我们在不影响对象本质的前提下,附加额外信息增强元编程能力。
Metadata附加的目标
首先要明确一点的是,Metadata不是任何对象/值都拥有的。只有如下的对象才可附加Metadata
- Symbol
- 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) "Metadata就这样哦")的更多相关文章
- Spark中决策树源码分析
1.Example 使用Spark MLlib中决策树分类器API,训练出一个决策树模型,使用Python开发. """ Decision Tree Classifica ...
- Kafka - 消费接口分析
1.概述 在 Kafka 中,官方对外提供了两种消费 API,一种是高等级消费 API,另一种是低等级的消费 API.在 <高级消费 API>一文中,介绍了其高级消费的 API 实现.今天 ...
- Jenkins: 基础篇(环境配置)
自动化领域比较有影响力的开源框架jenkins,确实比较强大,易用.很多公司将其用来做持续即成CI(continuous integration).为了拓展和强化自己的软件设计生态系统,也将很久前使用 ...
- Jenkins master在windows上安装
原文:http://www.cnblogs.com/itech/archive/2011/11/02/2233343.html 1 Jenkins Jenkins由以前的hudson更名而来.Jenk ...
- 用ingress的方式部署jenkins,启动后提示没有下载插件,未解决
[root@node2 .docker]# docker logs 5c3dd117a10dRunning from: /usr/share/jenkins/jenkins.warwebroot: E ...
- WPF 依赖属性源码 洞察微软如何实现DependencyProperty
依赖属性DependencyProperty是wpf最重要的一个类,理解该类如何实现对学习wpf帮助很大! 终于找到了该类的源码!仔细阅读源码,看看微软如何玩的花招! File: Base\Syste ...
- 玩转Kafka的生产者——分区器与多线程
上篇文章学习kafka的基本安装和基础概念,本文主要是学习kafka的常用API.其中包括生产者和消费者, 多线程生产者,多线程消费者,自定义分区等,当然还包括一些避坑指南. 首发于个人网站:链接地址 ...
- Windows上使用Vagrant打造Laravel Homestead可协同跨平台开发环境
1.简介 Laravel 致力于让整个 PHP 开发过程变得让人愉悦,包括本地开发环境,为此官方为我们提供了一整套本地开发环境 —— Laravel Homestead. Laravel Homest ...
- Jenkins介绍和安装及配合GitLab代码自动部署
Jenkins是什么? 基于JAVA的开源的自动化系统平台 加速自动化CI,CD任务及流水线,所有类型的任务:构建,测试,部署等 丰富的插件生态系统支持功能扩展,1400+插件和SCM,测试,通知,报 ...
随机推荐
- ThinkPHP5.0版本和ThinkPHP3.2版本的区别
5.0版本和之前版本的差异较大,本篇对熟悉3.2版本的用户给出了一些5.0的主要区别. URL和路由 5.0的URL访问不再支持普通URL模式,路由也不支持正则路由定义,而是全部改为规则路由配合变量规 ...
- Python教程(0)——介绍
What's Python? Python是一种编程语言,由荷兰人Guido van Rossum于1989年,为打发无聊的圣诞节而开发的. Python的优点是语法简洁,代码量比C/C++.Java ...
- 一天搞定CSS: overflow--14
overflow:针对超出父级的内容如何显示 代码演示 <!DOCTYPE html> <html> <head> <meta charset="U ...
- html表格表单标签的结合
今天我尝试将表格表单基本标签结合起来放在网页中,发现再没用表单元素中<form></form>时各类标签功能都可显示,只是不能提交网页,所有与提交网页的标签都不能使用提交功能, ...
- wpf XAML xaml 进行 数据绑定,Resource DataContext ElementName
先做个声明:这里绑定都在前台实现,至于后台怎么写,那比前台简单多了,但更常用的是xaml中绑定.我们分析下最简单的字符串绑定来弄清楚原理,其他的类推就是. 数据绑定主要是要弄清楚两个东西,一个是源So ...
- javacpp-opencv图像处理系列:国内车辆牌照检测识别系统(万份测试车牌识别准确率99.7%以上,单次平均耗时39ms)
javaCV图像处理系列: 一.javaCV图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体.位置.大小.粗度.翻转.平滑等操作 二.javaCV图像处理之2:实时视频添 ...
- python+selenium遇到鼠标悬停不成功可以使用js进行操作
问题:在定位这种悬停后出现下拉操作的时候,尝试了使用move_to_element的方法 # ele_logout = br.find_element_by_xpath('/html/body/div ...
- comm的用法
1.comm的功能 对两个排序过的文本文件进行逐行比较基本用法:comm -[123] file1 file2 2.例子 1)显示两个文本文件都有的行#comm -12 file1 file2 2)显 ...
- thinkphp3.2.3 版本使用redis缓存添加认证
我在使用thinkphp3.2.3的时候 发现如果是使用redis缓存 设置了认证的redis能连接成功 却无法 set 操作 ,检查发现是没有认证导致的 $redis->auth这一步没有, ...
- java源码学习(三)Enum
Enum Enum类是java.lang包中一个类,他是Java语言中所有枚举类型的公共基类. 一.定义 public abstract class Enum<E extends Enum< ...