【问题标题】:Is there any way to remove an R6 object using it's own method?有没有办法使用它自己的方法删除 R6 对象?
【发布时间】:2020-08-08 02:34:48
【问题描述】:

以下面给出的基本 R6 类为例:

library(R6)

Demo = R6Class("Demo",
           public = list(
             initialize = function(){
               message("demo object initialized!")
             },
             delete = function(){
               #should contain the logic to delete the object
               gc()
             },
             finalize = function(){
               message("demo object deleted!")
             } 
           ))

demoObj = Demo$new()
demoObj$delete()

删除函数内部的逻辑应该是什么?是否可以删除对象(自己)?

【问题讨论】:

  • 我不熟悉 r。但是,对于其他 OO 语言(例如 Java、Ruby),一旦不再引用对象,gc 就会完成。换句话说,对象不会删除自己。一旦不再使用,就会被垃圾回收。
  • 谢谢,我了解 gc 的使用,但想知道是否有任何方法可以使用 rm(obj) 之类的方法删除对象本身。

标签: r oop r6


【解决方案1】:

我不知道以这种方式让 R 中的对象“自毁”的任何直接方法。对象属于创建它的环境,有充分的理由将对象生命周期的控制权交给创建它的环境,而不是对象本身。

这并不意味着没有办法做到这一点,但实际上您必须允许对象在其父框架中查找其自己的名称(使用仅在设置删除过程后标识它的标志运动),然后在父框架中对该名称调用rm。所以像这样的表示:

library(R6)

Demo = R6Class("Demo",
           public = list(
             initialize = function(){
               message("demo object initialized!")
             },
             delete_flag = FALSE,
             delete = function(){
               self$delete_flag <- TRUE
               pf <- parent.frame()
               demos <- sapply(ls(pf), function(i) {
                          class(get(i, envir = pf))[1] == "Demo"
                        })
               this <- ls(pf)[demos][sapply(mget(ls(pf)[demos], envir = pf),
                      function(x) x$delete_flag)]
               rm(list = this, envir = pf)
               message("demo object deleted!")
             }
           ))

demoObj = Demo$new()
#> demo object initialized!

ls()
#> [1] "Demo"    "demoObj"

demoObj$delete()
#> demo object deleted!

ls()
#> [1] "Demo"

这是为了确保只删除正确的对象,例如;

demoObj1 = Demo$new()
#> demo object initialized!
demoObj2 = Demo$new()
#> demo object initialized!
demoObj3 = Demo$new()
#> demo object initialized!

demoObj2$delete()
#> demo object deleted!

ls()
#> [1] "Demo"     "demoObj1" "demoObj3"

你可以看到只有demoObj2删除了自己。

reprex package (v0.3.0) 于 2020 年 8 月 8 日创建

【讨论】:

  • 将 delete_flag 设为私有是否有意义,因为它仅供内部使用?
  • @AkshitAchara 是的,不过你需要一个 getter 函数才能读取它。
  • 谢谢,这个方法从父环境中删除对象。有没有办法查找对象的所有引用并删除它们,即如果另一个 R6 对象包含我们希望删除的对象,那么该对象也应该从那里删除。 (如果demos &lt;- c(demoObj1, demoObj2),那么demoObj1$delete() 也应该从演示中删除它)
  • @Akshit 不,没有简单的方法可以做到这一点,原因很简单,一个对象没有任何关于它指向什么以及它被赋予什么名称的信息。就像我说的,依靠对象自己的delete 方法来尝试摆脱它是一个真正的延伸。请相信我:无论你想做什么,都有更好的方法来做。考虑不同的设计,如果您遇到困难,这里有很多人可以提供帮助。
猜你喜欢
  • 2016-03-07
  • 1970-01-01
  • 2021-08-27
  • 2011-02-16
  • 1970-01-01
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 2012-12-05
相关资源
最近更新 更多