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会这样做,但我用那个什至没有成功。

0

评论由:gfredericks

{{reify}}实际上创建了两个对象 -- 第一个是通过 * } 创建的,然后>{{reify}}立即对其调用{{with-meta}},创建一个副本。

文档字符串说明了这种行为:"reify总是实现clojure.lang.IObj并将形式的元数据传递到创建的对象中。"

0

评论由:wagjo

哦,所以在reify中不能使用finalizer。我认为应该在文档中提及这一点。

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报告)
...