Clojure 规范和解构?

Clojure Spec and destructuring?

不确定如何编写规范来检查函数的解构参数。

如果我有这个简单的功能:

(defn make-name [[first last]]
  (str first " " last))

我为参数写了这个规范:

(s/def ::vstring2 (s/coll-of string? :kind vector? :count 2 :distinct false))

它工作正常:

(s/conform ::vstring2 ["Rich" "Hickey"])
=> ["Rich" "Hickey"]

但是当我尝试将它应用到函数时:

(s/fdef make-name
        :args ::vstring2
        :ret string?)

爆炸了:

(stest/check `make-name)
=>
({:spec #object[clojure.spec.alpha$fspec_impl$reify__2451
                0x7dd4c5ac
                "clojure.spec.alpha$fspec_impl$reify__2451@7dd4c5ac"],
  :clojure.spec.test.check/ret {:result #error{:cause "Wrong number of args (2) passed to: roster/make-name",

(...)

如何使用 ::vstring2 编写函数规范?还是我?

谢谢。

您只需要为函数的参数指定另一个规范,例如使用 s/cat:

(s/fdef make-name
  :args (s/cat :arg1 ::vstring2)
  :ret string?)

在您的示例中,:args 规范需要两个参数,因为您的 ::vstring2 规范是一个需要两个字符串的集合。通过此更改,函数 :args 规范知道它只需要 one 参数,该参数应符合 ::vstring2.

还有更多函数规范示例 here and here