3

我有一个采用以下形式的函数

(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 保持不变?

4

3 回答 3

2

这有效并覆盖:x传递给的任何值bar

(defn foo [& {:keys [ x y ]}]
   [x y])

(defn bar [ & args ]
   (apply foo (concat args [:x "blah"])))
于 2013-05-22T23:22:53.817 回答
2
(defn bar [& {:keys [y z] :as args}]
  (apply foo (apply concat (assoc args :x "blah"))))
于 2013-05-23T02:55:40.233 回答
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)))).

于 2013-05-22T23:38:39.593 回答