这与其他一些问题/bug 报告有关,但我没有找到专门针对这一点的。
因为 :or
分解为 get
调用中分解的键/符号等的缺失值,如果您用 :as
绑定一个对象并且在 :or
中包含默认值,对象将不具有这些默认值。
(defn example [{:keys [a b]
:or {a 1 b 2}
:as opts}]
(println a b opts))
(example {:a 5})
;=> 5 2 {:a 5}
这导致我们代码库中出现了微妙的错误,我们原本期望有默认值,但实际上却没有。或者我们使用了 {:pre [some-pred]}
来检查一个不变性,当我们修改函数以使用 :as
并包含特定值时,该不变性被违反。
要合并它们,您需要先构建映射,然后进行 opts (conj defaults-map opts)
,但这需要对键/符号/字符串进行第二次迭代,只选择在 :or
映射中的名称,并且需要创建另一个映射,或者可能反复调用 assoc
。
我认为这是可行的,但编写起来可能会有些麻烦。