Clojure强制性关键字参数

时间:2013-06-29 17:12:36

标签: clojure keyword-argument

我有这样的功能:

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

我这样称呼它:

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

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

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

4 个答案:

答案 0 :(得分:6)

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

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

当密钥为零时,这将抛出AssertionError。

答案 1 :(得分:2)

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

答案 2 :(得分: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))

答案 3 :(得分:0)

如果您想要更复杂的内容,请查看Validateurbouncer