zoukankan      html  css  js  c++  java
  • schema for clojure

    Schema for Clojure Data Shape

    Declaration and Validation


    1.何为schema

    schema是描写叙述数据形式的一种clojure数据结构,可用于文件、校验函数和数据。

    以下举个样例让大家对schema有个整体认识.

    例:

    (ns schema-examples

    (:require [schema.core :as s]))

    (def  s-type s/Str)

    (s/validate  s-type  "123")  ;; Success!

    (s/validate  s-type  123)   ;; Exception -- Value does not match schema:...


    2.schema在clojure中的使用

    (1)project.clj的:dependencies中加入“[prismatic/schema "0.3.1"]”包。

    (2)在命名空间的:require中增加“[schema.core :as s]”。


    3.定义数据类型

    (1)支持java所定义的全部数据类型(包含基本数据类型和复杂数结构),schema封装了好多Java的数据类型,如Int Str等。

    [详见](http://prismatic.github.io/schema/schema.core.html)

    例:(def data long)

    (def map-shape java.util.Map)

    (2)支持schema.core定义的数据类型

    例:(def s-data s/Int)

    (def s-str s/Str)

    (def s-keyword s/Keyword)

    (3)支持自己定义数据类型

    例:

    (def Data

      {:a {:b s/Str

          :c s/Int}

      :d [{:e s/Keyword

           :f [s/Num]}]})

    (4)能够利用schema提供的工具函数来定义类型

    例:

    定义一个数据必须是奇数且为长整形的:

    (def OddLong (s/both long (s/pred odd? 'odd?

    )))

    (都不用你再写一个检查函数了,非常方便啊。有木有!!)

    (5)对于Map的schema。在定义的时候还能够设定可选项

    如:

    (def FancyMap

     {(s/optional-key :foo) s/Keyword

       s/Str s/Str})

    (s/validate FancyMap {"a" "b"})

    (s/validate FancyMap {:foo :f "c" "d" "e" "f"})

    注意:key 和 value应该是成对出现或消失的。

    (s/validate FancyMap {:foo "c" "d" "e" "f"})  ;; Exception -- Value does not match schema:...

    (6)你能够用s/validate函数来检測你定义的数据是否满足你定义的类型。

    还能够用s/explain函数来检查某个类型的定义。

    如:

    (s/validate FancyMap {"a" "b"})

    (s/explain FancyMap)


    4.定义变量

    能够用schema.core中的def来定义一个变量, 如:

    (s/def foo :- long 2)

    要求用于变量初始化的值必须满足定义的schema.


    5.定义函数

    schema.core中封装了好多函数, 我们能够利用s/defn或s/fn来定义我们的函数,和用clojure的defn是一样样的.

    例:

    (s/defn deposite :- (s/maybe s/Int)

     [order-id :- (s/maybe s/Int) pay-type :- s/Str]

     ...)

       (1)假设想要对函数做类型检查,必须使用schema中封装的defn 或 fn来定义函数。这是运行类型检查的基础。可是是否进行类型检查,还有“开关”进行控制。

       (2)參数和返回值:能够用":-"符号来指定一个參数和返回值的类型(能够是自己定义类型)。

       (3)假设数据可能为nil时,能够用maybe函数来修饰。

       (4)假设想要对某个函数或者多个函数进行类型检查,能够用with-fn-validation来运行这些函数。如:

    (s/with-fn-validation

    (deposite 1 "yidong")

    (function2 ...)

    (function3 ...))

          * 这个相当于类型检查的“开关”,在測试代码中很实用。

    我们能够在測试的时候开启类型检查。而公布的时候则不须要开启。

       (5)假设想要一个函数总是运行类型检查,能够使用“^:always-validate”。如:

    (s/defn ^:always-validate finish-order :- Map

     [order-id :- s/Int pay-type :- s/Str pay-result :- s/Bool]

           *对于那些和用户输入相关的函数,能够使用该方法。


    6.schema的优点:

    (1)可自己定义数据类型。

    (2)可自由控制检測开关。

             比方,可在測试时打开类型检測。公布时关闭.

    (3)明白输入输出, 提高代码可读性。

             不须要为函数參数和返回值写一堆凝视:凝视和代码不同步,自然语言描写叙述的不明白、不一致,在每一个使用该数据的地方都要写一次凝视.


    7.schema的不足:

    (1)不能对数组的个数做限定,假设想定义仅仅有两个元素的数组"[Long Long]".

    个人想法:这不能算是不足。由于schema主要是做类型检測的,不是编译器。

    (2)不能定义某些复杂的类型。如想要给以下的数据结构定义一个类型:

    [[1 1.0] [2 2.0]]

    你可能会定义成:

    (def a [[s/Int double]])

    结果执行(s/validate a [[1 1.0] [2 2.0]])出错.

    定义成[[s/Num]]则执行正常.

    个人想法:数组中存放的元素的类型应该是一致的(C/C++/JAVA等语言中,数组中元素的类型不都是一致的么?), 你能够把它们封装在一个map或者类里。再来定义。


    8.schema支持的clojure版本号。

    文档上说是1.5.1 and 1.6.x,实际測试发现1.7.0-alpha也支持。

    *还支持ClojureScript(有须要的时候再研究,欢迎大家补充).



    以上是依据个人实践和查阅资料所总结出来的, 有不足或者错误之处,请大家补充和指正.


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    fabrci网络调优
    fabric链码容器
    fabric文档查阅
    fabric基础设施管理-(五)移除网络
    fabric源码编译
    fabric网络状态监控
    fabric基础设施管理-(六)配置管理
    Scheme宏基础入门(转载)
    GO语言程序中解决中文日期格式的解析问题
    临别之际
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4874908.html
Copyright © 2011-2022 走看看