Clojure中代理命名参数的惯用方法
我需要一个函数,它将的Clojure中代理命名参数的惯用方法,clojure,amazonica,Clojure,Amazonica,我需要一个函数,它将的sqs/receive message精简包装,以便添加默认等待时间。该函数需要一个队列URL,然后接受任意数量的可选命名参数,这些参数应原封不动地传递给sqs/receive message。我想这样称呼它: (my-receive-message "https://sqs.us-east-1.amazonaws.com/123/test-q" :max-number-of-messages 10
sqs/receive message
精简包装,以便添加默认等待时间。该函数需要一个队列URL,然后接受任意数量的可选命名参数,这些参数应原封不动地传递给sqs/receive message
。我想这样称呼它:
(my-receive-message "https://sqs.us-east-1.amazonaws.com/123/test-q"
:max-number-of-messages 10
:delete true)
(sqs/receive-message :queue-url "https://sqs.us-east-1.amazonaws.com/123/test-q"
:wait-time-seconds 20
:max-number-of-messages 10
:delete true)
这将导致调用sqs/receive message
,如下所示:
(my-receive-message "https://sqs.us-east-1.amazonaws.com/123/test-q"
:max-number-of-messages 10
:delete true)
(sqs/receive-message :queue-url "https://sqs.us-east-1.amazonaws.com/123/test-q"
:wait-time-seconds 20
:max-number-of-messages 10
:delete true)
这是我经常想做的事情,但我还没有找到一个好方法。有一种惯用的方法可以做到这一点吗?在合并的参数上使用
apply
(defn my-receive-message
[url & {:as args}]
(apply sqs/receive-message (-> {:queue-url url
:wait-time-seconds 20}
(merge args)
seq
flatten)))
您始终可以编写宏:
(defmacro my-receive-message [url & opts]
`(sqs/receive-message
~@(flatten (seq (merge {:queue-url url :wait-time-seconds 20}
(apply hash-map opts))))))
(请注意,这与Guillermo的函数几乎完全相同。主要区别在于您不必
应用sqs/receive message
——无引号拼接(~@
)隐式处理应用
部分。)如何销毁args参数?[url&{:as args}](为了避免应用散列映射args)另外,您可能希望以另一种方式进行合并,以便我的接收消息的调用方可以覆盖默认的waits这正是我要查找的!我错过的是seq
在我将地图展平之前将其展平。这真的很好,但我读过的每一本Clojure书中的“更喜欢函数而不是宏”这几个字仍在我耳边回响这通常是一条很好的经验法则。由于参数分解,Guillermo的函数更简单/更流畅,我想我可能也会选择函数版本。打得好,丹尼!