Clojure spec.alpha-如何(引用另一个参数)/(描述该参数集合应包括来自另一参数集合的值)



我需要什么:函数的规范,有两个参数:

  • 关键字和字符串的哈希映射
  • 一个向量,它可能有字符串或关键字,但如果它是关键字<strong],则它必须存在于哈希映射>中(第一个参数(

(你的答案不必涵盖所有这些,主要是我需要一种方法来告诉你,如果它是一个关键字,它必须存在于哈希图中(

这是我所拥有的:

(这是一个例子,表明可以访问里面的两个参数:args,我知道它不测试任何东西,总是失败,因为返回nil(

(ns my-example.core
(:require
[clojure.spec.alpha :as spec]))
(defn my-example [m v] nil)
(spec/fdef my-example
:args (fn [[m v]] nil))

这种fn是有效的(可以创建一个按照我的意愿工作的函数(,但它不是很有描述性,当它失败时(假设有(stest/instrument `my-example)),它只是向我显示函数体(像这样:(fn [[m v]] nil)(。

这是解决我问题的唯一方法还是有更好的方法?

我还试图定义一个规范并在里面使用:args:

(spec/def :my-example/my-check (fn [[m v]] nil))
(spec/fdef my-example
:args :my-example/my-check)

但结果是一样的。

:args的规范中,您可以指定任何您想要的谓词。请参阅fdef规范指南中提供的示例。举个例子,这里有一个代码片段,它主要适用于您的案例。我说";大部分是";因为第一个map参数的规范可能会更严格,以注意它是关键字到字符串的映射。comment表单中的表单显示了一些用法示例。

(ns example
(:require [clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as stest]))
(defn my-example [m v] nil)
(s/fdef my-example
:args (s/and (s/cat :m map? :v vector?)
#(every? (fn [x] (or (string? x)
(and (keyword? x)
(contains? (:m %) x))))
(:v %)))
:ret nil?)
(comment
(stest/instrument `my-example)
(my-example {:a "a" :b "b"} ["foo" :a "bar" :b]) ; => nil
(my-example {:a "a" :b "b"} ["foo" :a "bar" :c]) ; => spec exception
(my-example {:a "a" :b "b"} ["foo" :a "bar" 2]) ; => spec exception
)

最新更新