Clojure 规范和记录构造函数
Clojure spec and record constructors
如果我定义了如下记录:
(defrecord Person [name id])
及以下:
(s/def ::name string?)
(s/def ::id int?)
(s/def ::person (s/keys :req-un [::name ::id]))
如何确保您不能创建不符合 ::person 规范的 Person?换句话说,以下应该抛出异常:
(->Person "Fred" "3")
我试过了:
(s/fdef ->Person :ret ::person)
但是打电话:
(->Person "Fred" "3")
不引发异常。
但是:
(s/conform ::person (->Person "Fred" "3"))
确实产生了预期的效果:
:clojure.spec/invalid
谢谢
fdef
:ret 和 :fn 规范仅在 clojure.spec.test/check
测试期间检查,但您可以使用 fdef :args 规范在检测时检查构造函数的输入。
(s/fdef ->Person
:args (s/cat :name ::name :id ::id)
:ret ::person)
(require '[clojure.spec.test :as stest])
(stest/instrument `->Person)
(->Person "Fred" "3")
=> CompilerException clojure.lang.ExceptionInfo: Call to #'spec.examples.guide/->Person did not conform to spec:
In: [1] val: "3" fails spec: :spec.examples.guide/id at: [:args :id] predicate: int?
:clojure.spec/args ("Fred" "3")
:clojure.spec/failure :instrument
:clojure.spec.test/caller {:file "guide.clj", :line 709, :var-scope spec.examples.guide/eval3771}
使用匹配规范来宏化构造函数的 defrecord 和 fdef 的组合不会太难。
如果我定义了如下记录:
(defrecord Person [name id])
及以下:
(s/def ::name string?)
(s/def ::id int?)
(s/def ::person (s/keys :req-un [::name ::id]))
如何确保您不能创建不符合 ::person 规范的 Person?换句话说,以下应该抛出异常:
(->Person "Fred" "3")
我试过了:
(s/fdef ->Person :ret ::person)
但是打电话:
(->Person "Fred" "3")
不引发异常。
但是:
(s/conform ::person (->Person "Fred" "3"))
确实产生了预期的效果:
:clojure.spec/invalid
谢谢
fdef
:ret 和 :fn 规范仅在 clojure.spec.test/check
测试期间检查,但您可以使用 fdef :args 规范在检测时检查构造函数的输入。
(s/fdef ->Person
:args (s/cat :name ::name :id ::id)
:ret ::person)
(require '[clojure.spec.test :as stest])
(stest/instrument `->Person)
(->Person "Fred" "3")
=> CompilerException clojure.lang.ExceptionInfo: Call to #'spec.examples.guide/->Person did not conform to spec:
In: [1] val: "3" fails spec: :spec.examples.guide/id at: [:args :id] predicate: int?
:clojure.spec/args ("Fred" "3")
:clojure.spec/failure :instrument
:clojure.spec.test/caller {:file "guide.clj", :line 709, :var-scope spec.examples.guide/eval3771}
使用匹配规范来宏化构造函数的 defrecord 和 fdef 的组合不会太难。