Die*_*ngs 18 clojure clojure.spec
我用了最后几天深入挖掘了Clojure和ClojureScript中的clojure.spec.
到现在为止我觉得最有用的,使用规格为警卫:pre和:post在依赖于数据在一定格式的公共职能.
(defn person-name [person]
{:pre [(s/valid? ::person person)]
:post [(s/valid? string? %)]}
(str (::first-name person) " " (::last-name person)))
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是,我得到一个java.lang.AssertionError: Assert failed: (s/valid? ::person person)没有任何关于究竟没有达到规范的信息.
有没有人一个想法如何得到一个更好的错误信息中:pre或:post警卫?
我知道conform和explain*,但这对那些:pre或:post警卫没有帮助.
Ale*_*ler 11
在较新的alpha中,现在s/assert可用于断言输入或返回值与规范匹配.如果有效,则返回原始值.如果无效,则会在解释结果中引发断言错误.断言可以打开或关闭,甚至可以选择从编译的代码中完全省略,以产生0生产影响.
(s/def ::first-name string?)
(s/def ::last-name string?)
(s/def ::person (s/keys :req [::first-name ::last-name]))
(defn person-name [person]
(s/assert ::person person)
(s/assert string? (str (::first-name person) " " (::last-name person))))
(s/check-asserts true)
(person-name 10)
=> CompilerException clojure.lang.ExceptionInfo: Spec assertion failed
val: 10 fails predicate: map?
:clojure.spec/failure :assertion-failed
#:clojure.spec{:problems [{:path [], :pred map?, :val 10, :via [], :in []}], :failure :assertion-failed}
Run Code Online (Sandbox Code Playgroud)
我认为这个想法是你spec/instrument用来验证函数输入和输出而不是前后条件.
这篇博文的底部有一个很好的例子:http://gigasquidsoftware.com/blog/2016/05/29/one-fish-spec-fish/.快速摘要:你可以使用:args和:ret键定义一个函数的规范,包括输入和返回值(因此替换前置条件和后置条件),使用spec/fdef,检测它,并得到类似于使用explain时的输出不符合规格.
从该链接派生的最小示例:
(spec/fdef your-func
:args even?
:ret string?)
(spec/instrument #'your-func)
Run Code Online (Sandbox Code Playgroud)
这相当于给出了一个前提条件,即函数有一个整数参数和一个后置条件,它返回一个字符串.除了你得到更多有用的错误,就像你正在寻找.
官方指南中的更多细节:https://clojure.org/guides/spec ---请参阅标题"Spec'ing functions".
| 归档时间: |
|
| 查看次数: |
1770 次 |
| 最近记录: |