请在Clojure 2024 年度调查中分享您的想法!

欢迎!请访问关于页面以获取有关如何使用本站的更多信息。

0
Clojure

即使对象仍然可达,也会为具体化对象调用 Finalize。它将在适当时机第二次调用。

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

'user/x

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

<user$reifystrong1496 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
by

评论由:wagjo 发布

哦,所以终结者不适合使用在reify中。我认为文档中应该提到这一点。

0
by

评论者:gfredericks

为了好玩,你可以做一些技巧性的事情

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

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

`

(尚未实际运行此代码)

0
by

评论者:gfredericks

看起来由{{reify}}生成的类总是有一个带有元数据参数的构造函数,所以似乎完全消除了额外的对象也不是不可能的。

我会努力继续挖掘这个。

0
by
参考:[https://clojure.atlassian.net/browse/CLJ-1347](https://clojure.atlassian.net/browse/CLJ-1347)(由wagjo报告)
...