Clojure Spec 和解构赋值?

4

我不确定如何编写一个规范来检查函数的析构参数。

如果我有这个简单的函数:

(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编写函数Spec呢?还是说我需要使用它吗?
谢谢。

1
你可能还想看看s/tuple,而不是使用vector:https://clojure.org/guides/spec#_collections - Juraj Martinka
s/tuple 很有帮助,我正在使用它。谢谢 @JurajMartinka。 - ericky
1个回答

4

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

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

在你的示例中,:args规范期望两个参数,因为你的::vstring2规范是一个期望两个字符串的集合。通过这个更改,函数:args规范知道它只需要一个符合::vstring2的参数。
这里有更多的函数规范示例,可以在这里这里找到。

谢谢你再次帮助我,Taylor。我之前看了你提到的两个例子,但没有看到任何提示我添加:arg1的内容。 - ericky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接