请分享您的想法,参加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报告)
...