前言

 动态类型语言,少了静态类型语言必须声明变量类型的累赘,但也缺失了编译时类型检查和编译时优化的好处。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. 谷歌安装器扫描时提示“需要root权限”,不用root也可以的!

    能FQ的用户会用谷歌服务,一般的新手机没有安装谷歌框架,但是在用谷歌安装器安装谷歌市场时会提示"需要root权限",我用的是360手机,按照下面的教程搞好了: 安装完GSM包就可以 ...

  2. 推荐xamlspy

    xamlspy(http://xamlspy.com/) 如果在win32时代用过spy++的,都应该在silverlight/wpf时代用一下xamlspy,让你重新找到用spy++看别人程序的UI ...

  3. dedecms列表页调用子栏目列表,织梦首页调用栏目的子栏目标签代码

    dedecms列表页调用子栏目列表,织梦首页调用栏目的子栏目标签代码. dedecms列表页调用子栏目列表标签: {dede:channelartlist type='sun' }<a href ...

  4. 测序分析软件-trimmomatic的记录

    1.下载相关软件,网址:http://www.usadellab.org/cms/index.php?page=trimmomatic,它有源代码和二进制两种文件(建议都下载,然后合并成一个文件,因为 ...

  5. LANMP一键安装包 版本服务任你选 可安装单一服务

    介绍与使用 更多内容请到 乌龟运维 wuguiyunwei.com 请保证在系统原有yum源文件存在的情况下运行此脚本 以下以centos7.3为例: 下面以安装LNMP为例: ? 1 wget ht ...

  6. spring非controller类获取service方法

    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); pushMessageServ ...

  7. MyBatis介绍

    MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis 使用简单的 XML或注解用于配 ...

  8. [1] Report Fusioncharts

    图形报表之fusioncharts  

  9. jQuery时间日期插件laydate,兼容bootstrap

    解压后,将laydate整个文件放至您项目的任意目录,不要移动其文件结构,它们具有完整的依赖体系. 使用只需在页面引入laydate.js即可. 如果您的网站的js采用合并或模块加载,您需要打开lay ...

  10. Python的初步认识与基本模块的导入

    由于公司开发都使用了Python,老大说要每个人都会,前端也要学,所以就看着老大写的博客一步步来了,但是对于小白而言,一门新的语言总得跳许多坑.尤其是Mac安装Python,各种坑. 坑一.由于Mac ...