3

我有这样的功能:

(defn foo [{a :keya b :keyb}]
  (list a b))

我这样称呼它:

(foo {:keya "hi"}) ; Returns ("hi" nil)

如果我不提供keyb关键字参数,则需要 nil 。有没有办法确保它为它抛出异常而不是把它当作 nil。

(我知道我可以手动检查并抛出异常,但是是否有任何特殊选项可以强制执行约束。)

4

4 回答 4

6

您可以使用前提条件(http://clojure.org/special_forms#toc9)来断言密钥存在:

(defn foo [{a :keya b :keyb}] 
   {:pre [(not (nil? b))]}
   (list a b))

当键为 nil 时,这将引发 AssertionError。

于 2013-06-29T17:46:10.017 回答
2

不,但当然因为 Clojure 是一个 lisp,所以您可以定义自己的宏来自动为您处理无聊的“手动检查”。

于 2013-06-29T20:10:35.367 回答
2

aldazosa为您提供了正确的解决方案,但{:keya nil :keyb nil}也是有效的地图。要允许nil您可以使用值contains?而不是nil?检查:

(defn foo [{a :keya b :keyb :as m}]
  {:pre [(every? (partial contains? m)
                 [:keya :keyb])]}
  (list a b))
于 2013-06-30T11:55:18.710 回答
0

如果您想要更复杂的东西,请查看Validateur保镖

于 2013-06-30T10:14:06.803 回答