• Clojure的学习笔记(二)


    Metadata

    identical? 和 java 中的 == 运算符是一个意思。= 和 java 中的 equal 函数是一个意思。

    Metadata在Clojure中可以不改变数据的情况下给数据增加metadata,使用with-meta宏和meta宏

    (def stu {:name "Stu" :email "stu@thinkrelevance.com"})
    (def serializable-stu (with-meta stu {:serializable true}))
    

    那么取数据的结果如下:

    (meta stu)
     nil
    (meta serializable-stu)
     {:serializable true}
    

    可以用 ^ 代替 meta 来完成上面的工作

    当我们根据一个老对象创建一个新对象的时候,老对象的metadata就会跟随着来到新对象这里。

    metadata 可以用来给一个函数指定参数和返回值类型,这在传统的函数式编程中往往是没有的,这点缺失也往往成为函数式语言不适合调试的明证。很幸运的是Clojure通过metadata提供了类似的能力。

    比如下文我们定义了一个函数,这个函数的参数和返回值都是String类型的:

    (defn #^{:tag String} shout [#^{:tag String} s] (.toUpperCase s))
    

    由于metadata的tag参数太常用,在Clojure中可以简化为下面这个形式:

    (defn #^String shout [#^String s] (.toUpperCase s))
    

    这样,当你用一些不是String的参数来调用shout的时候就会爆出下面的错误:

    (shout 1)
    java.lang.ClassCastException: \ 
    java.lang.Integer cannot be cast to java.lang.String
    

    如果你觉得这样定义的函数看起来有点怪异,那么便可以把这个metadata的定义放到最后来做,不过与普通的函数定义有区别的地方在于,我们要用括号包裹起函数体:

    (defn shout 
        ([s] (.toUpperCase s)) 
        {:tag String})
    

    下面是一个有用的metadata的key列表

    :arglists doc函数调用时,参数信息

    :doc doc函数调用时候,文档信息

    :file 源代码

    :line 代码当前行数

    :macro 如果当前是宏则为真

    :name local name

    :ns namespace

    :tag 期望的返回值或者参数类型

    Metadata的read macro: ^#form 和 with-meta 还是不同的,一个是给编译器增加metadata,一个是给数据加的。

  • 相关阅读:
    goroutine
    golang package log
    golang单元测试
    golang 文件操作
    go递归打印指定目录下的所有文件及文件夹
    go语言切片作为函数参数的研究
    go数据类型之基本类型
    结束了
    codeforces358D Dima and Hares【dp】
    codeforces1081G Mergesort Strikes Back【期望dp+脑洞】
  • 原文地址:https://www.cnblogs.com/mmjx/p/2216780.html
Copyright © 2020-2023  润新知