2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!请查阅 关于 页面以获取更多关于该功能信息。

0
Clojure

这与许多其他问题/ العمليات Jira 相关,但我还没有发现一个专门针对这个问题。

因为如果使用了 get 调用的拆解值作为 not-found,当您使用 :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}

这导致了我们在代码库中出现了微妙的错误,我们原本期望存在默认值,但它们并没有出现,或者当我们修改函数以使用 :as 和具体的值时,我们没有使用 {:pre [some-pred]} 来检查一个不变性(该不变性被违反了)。

要合并它们,您需要构建一个映射,然后执行 opts (conj defaults-map opts),但这需要第二次遍历键/符号/字符串,只选择在 :or 映射中的名称,还需要创建一个新的映射,或者可能反复调用 assoc.

我认为这是可行的,但写起来可能会有些麻烦。

我想了解一下,这是否只是出于信息目的发布的,还是要求 Clojure 进行更改?

(改变在拆解时 :or 的行为将会是一个破坏性的语言变化 — :as 特具体地绑定原始映射值到符号)

编辑了
我希望对其进行修改。我发现它很令人困惑,在我教授Clojure时被一些人认为是一种尴尬和令人惊讶的行为。但预期大多数请求都会被拒绝,因为Clojure的大部分现有行为已经固定。最好是检查一下。

1 个答案

+1

Noah
 
最佳答案

这是语言的预期行为。:as关注解构提供的值。:keys或其他解构关于绑定值。:or关于提供缺失绑定值的默认值。如果您有“总是包含”默认值,那么您可能希望在解构之前这样做,例如

(defn example [opts]
  (let [defaults {:a 1 :b 2}
        defaulted-opts (merge defaults opts)
        {:keys [a b]} defaulted-opts]
    (println a b defaulted-opts)))

您可以合并一些,只是试着明确。

感谢您的回答。该页面上(https://clojure.org/reference/special_forms#binding-forms)暗示(通过使用 `init-expr`),`:as` 绑定的优先级比 `:or` 高,但这并不明确,也没有示例表明它们不起作用。您是否接受一个表明该行为的补丁?
by
在这种情况下,我宁愿有一个关于这个问题的案例,而不是PR
by
好的,谢谢。
...