我对Clojure很新,通过阅读学习Clojure 良好的开源代码。所以我选择Ring并开始阅读 代码但卡在assoc-query-params函数中。 (位于ring.middleware/params.clj)
我无法理解为什么会使用“merge-with”。 任何人都可以帮我理解这段代码吗?
(defn- assoc-query-params
"Parse and assoc parameters from the query string with the request."
[request encoding]
; I think (merge request (some-form)) is enough
; but the author used merge-with with merge function.
(merge-with merge request
(if-let [query-string (:query-string request)]
(let [params (parse-params query-string encoding)]
{:query-params params, :params params})
{:query-params {}, :params {}})))
答案 0 :(得分:4)
merge
函数的 Here's the description:重写它说如果一个键被满足不止一次,那么将选择最新地图中的值。在您发布的示例中,这意味着:query-params
:params
的值将从函数的尾部按原样获取,而不是将它们与请求中的内容组合。
让我们看看这个例子:
(def m {:a {:a-key1 "value1"} :b {:b-key1 "value3"} :c {}})
(def m2 {:a {:a-key2 "value2"} :b {}})
(merge m m2)
;-> {:a {:a-key2 "value2"}, :b {}, :c {}}
(merge-with merge m m2)
;-> {:a {:a-key1 "value1", :a-key2 "value2"}, :b {:b-key1 "value3"} :c {}}
所以(merge-with merge ...)
构造为我们提供了一种在地图中合并地图的方法。您可以通过以下方式查看:merge-with将按键(:a
:b
:c
在我们的示例中)对所有键/值对进行分组,并将merge应用于其值。
{:a (merge {:a-key1 "value1"} {:a-key2 "value2"})
:b (merge {:b-key1 "value3"} {})
:c (merge {})}
处理完毕后,我认为assoc-query-params
作者的初衷是扩展:query-params
和:params
,而不是完全取代它们。