【问题标题】:Is there a destructor in R reference class?R参考类中有析构函数吗?
【发布时间】:2014-08-13 14:20:29
【问题描述】:

作为一个测试:

myclass = setRefClass("myclass",
                       fields = list(
                           x = "numeric",
                           y = "numeric"
                       ))


myclass$methods(
    dfunc = function(i) {
        message("In dfunc, I save x and y...")
        obj = .self
        base::save(obj, file="/tmp/obj.rda")
    }
    )

myclass$methods(
    print = function() {
            if (.self$x > 10) {
                stop("x is too large!")
            }
    message(paste("x: ", .self$x))
    message(paste("y: ", .self$y))
    }
    )

myclass$methods(
    initialize = function(x=NULL, y=NULL, obj=NULL) {
        if(is.null(obj)) {
            .self$x = x
            .self$y = y
        }
        else {
            .self$x = obj$x
            .self$y = obj$y
        }
    }
)


myclass$methods(
finalize = function() {
    message("I am finalizing this thing...")
}
)

然后尝试创建和删除一个对象:

u = myclass(15, 6)
u$print()
rm(u)

finalize 函数根本没有被调用...

【问题讨论】:

    标签: r reference-class


    【解决方案1】:

    当您调用 rm 时,您只需从环境中删除对象引用,但不会破坏元素。
    这是垃圾收集器的工作,旨在在对象不再有引用时自动销毁对象(如本例中)。反正垃圾回收器是由一些特殊事件触发的(比如内存占用过多等),所以调用rm时不会自动调用(以后可能会调用)。

    无论如何,您可以通过调用gc() 来强制垃圾收集器,即使通常不鼓励这样做。

    u = myclass(15, 6)
    rm(u)
    gc()
    
    # > I am finalizing this thing...
    

    运行上面的代码可以看到,你的finalize方法确实是在gc()之后调用的

    【讨论】:

    • 谢谢。另一个有趣的事情是,如果我将 x 设置为只读的 myclass$lock("x"),那么尝试为 x 设置新值也会调用 finalize(),这是为什么呢?
    • @qed:有趣,你能发一个例子说明你在锁定后如何设置 x 吗?
    • 哦,对不起,不能再重复了,一定是个意外,我猜的时候GC正好在工作。
    • @qed:我明白了,但我仍然对你如何设置“x”感兴趣...它应该引发错误...
    • 是的,它确实引发了错误。我刚刚做了类似 obj$x = 222 的操作。
    猜你喜欢
    • 2018-09-20
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 2010-09-15
    相关资源
    最近更新 更多