前言

 动态类型语言,少了静态类型语言必须声明变量类型的累赘,但也缺失了编译时类型检查和编译时优化的好处。cljs虽然作为动态类型语言,但其提供Metadata让我们在必要的时候可选择地补充类型提示,以便提高代码可读性和供编译器优化使用。除了上述以外,Metadata还让我们在不影响对象本质的前提下,附加额外信息增强元编程能力。

Metadata附加的目标

 首先要明确一点的是,Metadata不是任何对象/值都拥有的。只有如下的对象才可附加Metadata

  1. Symbol
  2. Var
  3. Collections(List,Map,Vector,Set)
  4. Record
  5. 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就这样哦")的更多相关文章

  1. Spark中决策树源码分析

    1.Example 使用Spark MLlib中决策树分类器API,训练出一个决策树模型,使用Python开发. """ Decision Tree Classifica ...

  2. Kafka - 消费接口分析

    1.概述 在 Kafka 中,官方对外提供了两种消费 API,一种是高等级消费 API,另一种是低等级的消费 API.在 <高级消费 API>一文中,介绍了其高级消费的 API 实现.今天 ...

  3. Jenkins: 基础篇(环境配置)

    自动化领域比较有影响力的开源框架jenkins,确实比较强大,易用.很多公司将其用来做持续即成CI(continuous integration).为了拓展和强化自己的软件设计生态系统,也将很久前使用 ...

  4. Jenkins master在windows上安装

    原文:http://www.cnblogs.com/itech/archive/2011/11/02/2233343.html 1 Jenkins Jenkins由以前的hudson更名而来.Jenk ...

  5. 用ingress的方式部署jenkins,启动后提示没有下载插件,未解决

    [root@node2 .docker]# docker logs 5c3dd117a10dRunning from: /usr/share/jenkins/jenkins.warwebroot: E ...

  6. WPF 依赖属性源码 洞察微软如何实现DependencyProperty

    依赖属性DependencyProperty是wpf最重要的一个类,理解该类如何实现对学习wpf帮助很大! 终于找到了该类的源码!仔细阅读源码,看看微软如何玩的花招! File: Base\Syste ...

  7. 玩转Kafka的生产者——分区器与多线程

    上篇文章学习kafka的基本安装和基础概念,本文主要是学习kafka的常用API.其中包括生产者和消费者, 多线程生产者,多线程消费者,自定义分区等,当然还包括一些避坑指南. 首发于个人网站:链接地址 ...

  8. Windows上使用Vagrant打造Laravel Homestead可协同跨平台开发环境

    1.简介 Laravel 致力于让整个 PHP 开发过程变得让人愉悦,包括本地开发环境,为此官方为我们提供了一整套本地开发环境 —— Laravel Homestead. Laravel Homest ...

  9. Jenkins介绍和安装及配合GitLab代码自动部署

    Jenkins是什么? 基于JAVA的开源的自动化系统平台 加速自动化CI,CD任务及流水线,所有类型的任务:构建,测试,部署等 丰富的插件生态系统支持功能扩展,1400+插件和SCM,测试,通知,报 ...

随机推荐

  1. crontab表达式执行时间计算,crontab在线测试

    熟悉Unix和Linux的朋友都知道Crontab表达式,通过crontab指令可以周期性调用或执行某个程序.   但是大家写完crontab表达式后,心里总是担心表达式写的不对,可以又没法去验证.比 ...

  2. 一个想法照进现实-《IT连》创业项目:直觉型面试招聘的漏洞

    前言: 创业转眼又过去了一个月,是时候抽时间写写文向大伙继续汇报进度了. 还记得上一篇创业文章,我还在说:创业时该不该用新手程序员. 嗯,然后,然后,报应就来了:所以这篇要写写自己在新人招聘上出现的问 ...

  3. centos nginx-1.10.3 安装

    wget http://nginx.org/download/nginx-1.13.1.tar.gz nginx 依赖 pcre 库,要先安装pcre,因为nginx 要在rewrite 要解析正则表 ...

  4. 写了一个Mac快速设置、打开和关闭Web代理的Shell命令

    缘由(痛点) 每次在Mac上设置Web代理,都需要点开"系统偏好设置 -- 网络 -- 高级 -- 代理",然后分别设置Web代理(HTTP)和安全Web代理(HTTPS),设置完 ...

  5. JS中的函数传参

    前言: 函数分为有参有返回值,有参无返回值,无参无返回值,无参有返回值:那么对于无参数的函数你想使用函数的调用怎么办呢?如果你想封装一个代码,实现多种功能,但是形参大于实参或者实参大于形参又该如何?本 ...

  6. Deep Q-Network 学习笔记(一)—— Q-Learning 学习与实现过程中碰到的一些坑

    这方面的资料比较零散,学起来各种碰壁,碰到各种问题,这里就做下学习记录. 参考资料: https://morvanzhou.github.io/ 非常感谢莫烦老师的教程 http://mnemstud ...

  7. Perl正则表达式例子

    Perl正则表达式 一.介绍 正则表达式各语言都有自己的规范,但是基本都差不多,都是由元字符的组合来进行匹配:由于Nmap内嵌的服务与版本探测是使用的Perl正则规范,因此此篇博客记录一下Perl正则 ...

  8. jeecg 弹出框 点击按钮回调父页面 返回值

    jeecg 弹出框 点击按钮回调父页面 返回值 <t:base type="jquery"></t:base> <t:base type=" ...

  9. 如何卸载CentOS自带的apache

    查看安装的组件: rpm -qa | grep httpd 如果预装有apache,那么会显示像httpd-2.2.3-22.el5.centos这种的组件名. 卸载组件: rpm -e httpd- ...

  10. Charles抓包工具安装与配置

    在实际开发中,我们需要时常抓取线上的请求及数据,甚至是请求的html文档,js,css等静态文件来进行调试.在这里,我使用charles来进行以上操作.但是呢,charles需要进行一系列配置才能达到 ...