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

欢迎!有关如何使用本网站的信息,请参阅关于页面。

0
Clojure

即使实体化对象仍然可达,也会为它们调用Finalize。它会在正确的时间再次被调用。

`
user=> (def x (reify Object (finalize [o] (println "OH MY!"))))

'user/x

user=> (System/gc)
nil
OH MY!
user=> x

<user$reify1496 user$reify1496@53fb35af>

user=> (System/gc)
nil
user=> (def x nil)

'user/x

user=> (System/gc)
nilOH MY!
`

Deftype看起來可以正常工作

`
user=> (deftype T [] Object (finalize [o] (println "great success")))
user.T
user=> (def y (->T))

'user/y

user=> (System/gc)
nil
user=> (def y nil)

'user/y

user=> (System/gc)
great success
`

6 个答案

0

评论者:alexmiller

备注:调用System/gc并不一定会使finalizers在第一次尝试时运行 - 对于我来说,有时需要超过一次才能成功。你可能会认为System/runFinalizers会这样做,但我完全没 luck at all with that。

0

评论者:gfredericks

{{reify}}实际上创建了两个对象——第一个由 * } 创建,然后{{reify}}立即在它上面调用{{with-meta}},创建一个副本。

文档大致描述了这种行为:“reify始终实现clojure.lang.IObj并将形式的元数据传输到创建的对象中。”

0

评论由:wagjo 发起

哦,所以finalizer在reify中是禁止的。我认为应该在文档中提到。

0

评论者:gfredericks

为了乐趣,你可以做一些狡猾的事情,比如

`
^::second-object
(reify Object
(finalize [self]

(when (::second-object (meta self))
  ...)))

`

(尚未实际运行此代码)

0

评论者:gfredericks

看起来{{reify}}生成的类总是有一个带有元数据参数的构造函数,因此看起来完全可以彻底删除额外的对象。

我将尝试继续挖掘这个问题。

0
参考: https://clojure.atlassian.net/browse/CLJ-1347(报告人:wagjo)
...