构造一个映射以传递给将解构它的函数

时间:2013-02-22 16:50:46

标签: clojure

我正在尝试找到一种方法来构建一个参数来传递给这个函数(它是托盘的一部分):

(defn node-spec [& {:keys [image hardware location network qos] :as options}]
  {:pre [(or (nil? image) (map? image))]}
  options)

这种用法有用:

(node-spec :location {:location-id "eu-west-1a"}, :image {:image-id "eu-west-1/ami-937474e7"} :network {})

但是:location和:image位对于我想要配置的所有机器都是通用的,而:network {}位对于每个节点是不同的。所以我想把公共位解析出来并做这样的事情:

(def my-common-location-and-image {:location {:location-id "eu-west-1a"}, :image {:image-id "eu-west-1/ami-937474e7"}} )
(node-spec (merge {:network {:security-groups [ "group1" ] }} my-common-location-and-image ))
(node-spec (merge {:network {:security-groups [ "group1" ] }} my-common-location-and-image ))

但这不起作用。合并的映射被解析为缺少其值的单个键。所以我试过

(node-spec :keys (merge {:network {:security-groups [ "group1" ] }} my-common-location-and-image ))

(node-spec :options (merge {:network {:security-groups [ "group1" ] }} my-common-location-and-image ))

但这也不起作用。我觉得我正试图逆转或超越node-spec参数中的解构。我究竟做错了什么?或者我的目标是分解一些关键/价值对是不可能的?

1 个答案:

答案 0 :(得分:0)

问题是node-spec函数期望序列而不是映射。这是因为被解构的是一系列可以按键值对分组的事物。

所以,而不是传递这个:

{:image {:image-id "eu-west-1/ami-937474e7"}, :location {:location-id "eu-west-1a"}, :network {:security-groups ["group1"]}}

我们需要通过这个:

'(:image {:image-id "eu-west-1/ami-937474e7"} :location {:location-id "eu-west-1a"} :network {:security-groups ["group1"]})

这意味着这将有效:

(apply node-spec
       (reduce concat
               (merge {:network {:security-groups ["group1"]}}
                      my-common-location-and-image)))