我有一个采用以下形式的功能
(defn foo [& {:keys [x y z]}]
...)
我想创建一个只占用y和z键的函数,但总是给x赋予相同的值。我可以像这样写
(defn bar [& {:keys [y z]}]
(foo :x "blah" :y y :z z))
我唯一的问题是我必须再次重复{:keys ...}位,并且实际的函数foo有更多的键,这可能在将来发生变化。有没有什么方法可以让bar接受任何键值对,并将它们全部传递给foo,同时确保x保持不变?
答案 0 :(得分:2)
这有效并覆盖传递给:x
的任何bar
值:
(defn foo [& {:keys [ x y ]}]
[x y])
(defn bar [ & args ]
(apply foo (concat args [:x "blah"])))
答案 1 :(得分:2)
(defn bar [& {:keys [y z] :as args}]
(apply foo (apply concat (assoc args :x "blah"))))
答案 2 :(得分:1)
当您使用&符号(&)时,您声明了一个可变参数函数。 你可能不需要你的函数是可变的。 你可以这样做:
(defn foo [{:keys [x y z]}]
[x y z])
(defn bar [{:keys [y z] :as args}]
(foo (assoc args :x "blah")))
您将使用以下地图致电bar
:(bar {:y 20 :z 10})
。如果您确实需要bar
作为可变函数,则可以执行此操作(foo
与上面相同):
(defn bar [& {:keys [y z] :as args}]
(foo (assoc args :x "blah"))
您将继续这样致电bar
:(bar :y 10 :z 20)
。您也可以使foo
变量,但您必须使用类似(flatten (map list (keys args) (vals args))))
的内容重新创建参数列表。