Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 解构时所需的密钥_Clojure - Fatal编程技术网

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)