4

有没有办法允许 S4 对象的方法直接调整该对象插槽内的值,而无需将整个对象复制到内存中,并且必须在方法结束时将其重新写入父环境?现在我有一个对象,它有插槽,它可以跟踪自己的状态。我调用了一个将其推进到下一个状态的方法,但现在似乎我必须将每个值(或调用该方法的对象的副本)分配()回父环境。结果,面向对象的代码似乎比在循环中简单地调整各种状态变量的代码运行慢很多。

4

3 回答 3

4

R 具有三个面向对象 (OO) 系统:S3S4参考类(后者曾一度被称为 [[R5]],但它们的正式名称是参考类)。

引用类(或引用类)是 R 2.12 中的新内容。它们满足了对可变对象的长期需求,这些对象以前由 R.oo、proto 和 mutatr 等非核心包填充。虽然核心功能是可靠的,但参考类仍在积极开发中,一些细节将会改变。参考类的最新文档总是可以在 ?ReferenceClasses 中找到。

参考类与 S3 和 S4 之间有两个主要区别:

  • Refclass 对象使用消息传递 OO
  • Refclass 对象是可变的:在修改语义上通常的 R 副本不适用。

这些属性使该对象系统的行为更像 Java 和 C#。在这里阅读更多:

  1. http://adv-r.had.co.nz/R5.html

  2. http://www.inside-r.org/r-doc/methods/ReferenceClasses

于 2014-08-29T17:08:00.770 回答
3

我自己在 R-list 上问了这个问题,并找到了一种解决方法来模拟通过引用传递,其风格为:

eval(
  eval(
     substitute(
        expression(object@slot <<- value)
     ,env=parent.frame(1) )
  )
)

远非我想说的最干净的代码......

来自 R-help 列表的建议使用环境来处理这些情况。编辑:插入调整代码。

setClass("MyClass", representation(.cache='environment',masterlist="list"))

setMethod("initialize", "MyClass",
  function(.Object, .cache=new.env()) {
    .Object@masterlist <- list()
    callNextMethod(.Object, .cache=.cache)
  })

sv <- function(object,name,value) {} #store value

setMethod("sv",signature=c("MyClass","character","vector"),
  function(object, name, value) {
    object@.cache$masterlist[[name]] <- value
  })

rv <- function(object,name) {} #retrieve value

setMethod("rv",signature=c("MyClass","character"),
  function(object, name) {
    return(object@.cache$masterlist[[name]])
  })
于 2010-08-30T16:06:39.693 回答
1

据我所知(如果我理解正确的话),您必须重新复制整个对象。您不能轻易地通过引用传递值,它总是“按值”传递。因此,一旦您修改(副本)您的对象,您需要将其重新复制回您的对象。

John Chamber 在他的《数据分析软件》一书中对此非常明确。这是一种避免意外或副作用的方法。

我认为使用环境有一些解决方法,但我对此无能为力。

于 2010-08-05T15:35:07.313 回答