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

欢迎!请查看 关于页面了解有关如何使用本站的一些更多信息。

0
Clojure

应完全禁止对可变字段的闭包(并生成编译器异常),而不仅仅是当尝试设置!它们时。因为可变字段的改变不会传播到闭包中的字段,这会导致令人意外的错误

`
(defprotocol P
(-set [this])
(-get [this])
(-get-fn [this]))

(deftype T [^:unsynchronized-mutable val]
P
(-set [this] (set! val :bar))
(-get [this] val)
(-get-fn [this] (fn [] val)))

(def x (->T :foo))

(def xf (-get-fn x))

user> (-set x)
:bar
user> (-get x)
:bar
user> (xf)
:foo ;; 应该是 :bar !!!
`

4 个答案

0

评论由:wagjo

相关问题 CLJ-274

0

评论由:gshayban

在给定的示例中,闭包发生之前是 set!,因此闭包获取的是值,而不是可赋值的容器。这与语言的其余部分保持一致(按值传递,而不是可变容器传递)

0

评论由:wagjo

感谢您的解释。这个工单是关于一个提议,即在重写可变字段时应该抛出错误,而不是返回一个值。如果需要返回值,必须使用显式的 let 绑定。到目前为止,我没有找到任何有效的用例,其中重写可变字段并获得重写的值是预期和希望的行为。

0
参考: https://clojure.atlassian.net/browse/CLJ-1560 (由 wagjo 提报)
...