(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,测试,通知,报 ...
随机推荐
- JVM-5.字节码执行引擎
一.概述 二.栈帧结构 三.方法调用 四.方法执行 一.概述 虚拟机与物理机 虚拟机是一个相对于物理机的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器.硬件. ...
- 克隆 CentOS 后系统启动问题解析
问题背景: 虚拟机:VMware Workstation. 操作系统:CentOS,是Linux发行版之一. 问题: 原因:虚拟机的服务没有开启(虚拟机开启一般比较占内存,所有多数人都设置成手动开启) ...
- Thrift总结(一)介绍
这段时间,一直在整理公司的内部 rpc 服务接口,面临的一个问题就是:由于公司内部的系统由几个不同的语言编写的.C# ,java,node.js 等,如何实现这些内部系统之间的接口统一调用,确实是比较 ...
- 在Quo.js下Tap和singleTap的区别
前两天上网搜开发手机页面的JS,看到了Quo.js下载下来后来看了一下,支持的触屏手势挺多的,在一般的开发中应该够用了,更让我喜欢它的一点是它跟JQ差不多(虽然功能不如JQ强大但是语法基本一致).这就 ...
- openresty使用笔记(一)
背景介绍 游戏经过一段时间的运营,发现了原来的设计缺陷太多,所以决定重新设计架构.使用到nginx作为核心并通过lua+redis设计实现自己的负载分配方案.先看看下面这张简单的架构图吧~ 从图上看, ...
- 前台跨站点获取session
var sessionId = System.Web.HttpContext.Current.Response.Cookies[System.Web.Security.FormsAuthenticat ...
- 学习mysql语法--基础篇(一)
前 言 mysql mysql语法--本篇学习都是通过使用Navicat Premium(数据库管理工具),连接mysql数据. 本篇学习主要有两个部分: 一.创建用户,创建数据库,给 ...
- Rest模式get,put,post,delete含义与区别(转)
POST /uri 创建 DELETE /uri/xxx 删除 PUT /uri/xxx 更新或创建 GET /uri/xxx 查看 GET操作是安全的.所谓安全是指不管进行多 ...
- excel转html 实现在线预览
首先说一下,本人发布的代码都是经过本人亲测,并且用在实际项目中.如果觉得可以,希望大家点个赞,谢谢大家. 有什么问题,大家评论出来,一起交流.好了,不废话了,下面来说一说这个东西怎么做. 网上也有许多 ...
- DDD理论学习系列(8)-- 应用服务&领域服务
DDD理论学习系列--案例及目录 1. 引言 单从字面理解,不管是领域服务还是应用服务,都是服务.而什么是服务?从SOA到微服务,它们所描述的服务都是一个宽泛的概念,我们可以理解为服务是行为的抽象.从 ...