Clojure 解构时所需的密钥
如果您试图解构的键不在传递给函数的映射中,是否有方法引发异常?这是宏的一个好用例吗 例如:Clojure 解构时所需的密钥,clojure,Clojure,如果您试图解构的键不在传递给函数的映射中,是否有方法引发异常?这是宏的一个好用例吗 例如: (defn x[{:keys[ab]}](println a b)) 我希望这个能起作用: (x{:a1:b2}) 但这会引发异常(:b缺失) (x{:a1})那么a呢 编辑:是的,您可以使用宏来处理此问题。也许是这样的: (defmacro defnkeys [name bindings & body] `(defn ~name [{:keys ~bindings}] {:pre
(defn x[{:keys[ab]}](println a b))
我希望这个能起作用:
(x{:a1:b2})
但这会引发异常(:b缺失)
(x{:a1})
那么a呢
编辑:是的,您可以使用宏来处理此问题。也许是这样的:
(defmacro defnkeys [name bindings & body]
`(defn ~name [{:keys ~bindings}]
{:pre ~(vec (map #(list 'some? %) bindings))}
~@body))
(defnkeys foo [a b]
(println a b))
(foo {:a 1 :b 2})
(foo {:a 1}) ;; AssertionError Assert failed: (some? b)
(foo {:a 1 :b nil}) ;; AssertionError Assert failed: (some? b)
先决条件似乎很完美。如果我想在不重复两次键(定义和预设置)的情况下执行此操作,我需要使用宏吗?(如果有用的话,我可以提供更多的上下文)太棒了!仅供参考,我必须从clojure 1.5切换到1.6才能使您的宏正常工作。@spike
some?
是在1.6中添加的-您可以完全删除它,但失败的断言看起来是这样的:AssertionError Assert failed:b
-信息量不大,如何使用新的clojure.spec机制处理它?
(defmacro defnkeys [name bindings & body]
`(defn ~name [{:keys ~bindings}]
{:pre ~(vec (map #(list 'some? %) bindings))}
~@body))
(defnkeys foo [a b]
(println a b))
(foo {:a 1 :b 2})
(foo {:a 1}) ;; AssertionError Assert failed: (some? b)
(foo {:a 1 :b nil}) ;; AssertionError Assert failed: (some? b)