Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
S4类:在不返回对象(R)的情况下更新另一个方法中的插槽_R_Oop_S4 - Fatal编程技术网

S4类:在不返回对象(R)的情况下更新另一个方法中的插槽

S4类:在不返回对象(R)的情况下更新另一个方法中的插槽,r,oop,s4,R,Oop,S4,对于我正在处理的一个R包(它创建了一个S4类),我想延迟加载一些数据,直到用户真正请求它为止(因为它可能是必需的,也可能不是必需的,加载它需要一段时间)。这需要我在它的getter(又名accessor)方法中设置一个插槽的值,如果它以前没有被加载过的话。但我无法获得“stick”的新值。以下是一份: setClass(“A”,表示法(value=“numeric”)) setGeneric(“value由@Alexis发表的评论提到了R6类。当我被要求为我当前的项目(针对BioConducto

对于我正在处理的一个R包(它创建了一个S4类),我想延迟加载一些数据,直到用户真正请求它为止(因为它可能是必需的,也可能不是必需的,加载它需要一段时间)。这需要我在它的getter(又名accessor)方法中设置一个插槽的值,如果它以前没有被加载过的话。但我无法获得“stick”的新值。以下是一份:

setClass(“A”,表示法(value=“numeric”))

setGeneric(“value由@Alexis发表的评论提到了R6类。当我被要求为我当前的项目(针对BioConductor)创建S4类时,R6 ReferenceClass文档中的以下句子吸引了我的眼球:“引用类作为S4类实现,数据部分类型为“environment”。”

因此,如果我在使用S4类时真的需要可变元素,我可以如下模拟R6:

setClass("A", representation(inMutable = "ANY", 
                             .env = "environment"))

A = function(inMutable = NULL, mutable = NULL) {
  x <- new("A", 
           inMutable = inMutable,
           .env = new.env())
  x@.env$mutable  = mutable
  x@inMutable <- inMutable
  x
}

setGeneric("inMutable<-", function(x, value) standardGeneric("inMutable<-"))
setGeneric("inMutable", function(x) standardGeneric("inMutable"))
setGeneric("mutable<-", function(x, value) standardGeneric("mutable<-"))
setGeneric("mutable", function(x) standardGeneric("mutable"))

#setter
setMethod("inMutable<-", signature("A", "numeric"),
          function(x, value) 
          {
            x@inMutable <- value
            x
          })    

#getter
setMethod("inMutable", signature("A"),
          function(x) 
          {
            if (!length(x@inMutable))
              message("Hmmm, you haven't initialized a value for 'inMutable'.",
                      " I'm afraid I can't do anything about that now.")
            x@inMutable
          })    

#setter
setMethod("mutable<-", signature("A", "numeric"),
          function(x, value) 
          {
            x@.env$mutable <- value
            x
          })    

#getter (mutable!)
setMethod("mutable", signature("A"),
          function(x) 
          {
            if (!length(x@.env$mutable)) {
              message("Ah. You haven't initialized a value for 'mutable'. ",
                      "Lucky for you I can initialize it for you now.")
              x@.env$mutable = 12
            }
            x@.env$mutable
          })    
setClass(“A”,表示法(inMutable=“ANY”,
.env=“环境”))
A=函数(inMutable=NULL,mutable=NULL){
x不可变(a)不可变(a)
[1] 18
> 

显然,引用类和R6提供了一个更丰富、更健壮的解决方案,但在紧要关头,这似乎是一个可行的S4选项。当然,我还没有在野外彻底测试它,看看它可能在哪里崩溃。

查看
setRefClass
或R6包的文档。S4没有传统的OOP可变性。谢谢@Alexis,我必须在我当前的项目中使用S4,但是这些文档让我想到了一个可能的解决方法(见下面我的答案)。
> a <- new("A")
> value(a)
[1] 20
> a
An object of class "A"
Slot "value":
numeric(0)
setClass("A", representation(inMutable = "ANY", 
                             .env = "environment"))

A = function(inMutable = NULL, mutable = NULL) {
  x <- new("A", 
           inMutable = inMutable,
           .env = new.env())
  x@.env$mutable  = mutable
  x@inMutable <- inMutable
  x
}

setGeneric("inMutable<-", function(x, value) standardGeneric("inMutable<-"))
setGeneric("inMutable", function(x) standardGeneric("inMutable"))
setGeneric("mutable<-", function(x, value) standardGeneric("mutable<-"))
setGeneric("mutable", function(x) standardGeneric("mutable"))

#setter
setMethod("inMutable<-", signature("A", "numeric"),
          function(x, value) 
          {
            x@inMutable <- value
            x
          })    

#getter
setMethod("inMutable", signature("A"),
          function(x) 
          {
            if (!length(x@inMutable))
              message("Hmmm, you haven't initialized a value for 'inMutable'.",
                      " I'm afraid I can't do anything about that now.")
            x@inMutable
          })    

#setter
setMethod("mutable<-", signature("A", "numeric"),
          function(x, value) 
          {
            x@.env$mutable <- value
            x
          })    

#getter (mutable!)
setMethod("mutable", signature("A"),
          function(x) 
          {
            if (!length(x@.env$mutable)) {
              message("Ah. You haven't initialized a value for 'mutable'. ",
                      "Lucky for you I can initialize it for you now.")
              x@.env$mutable = 12
            }
            x@.env$mutable
          })    
> a <- A()
> mutable(a)
Ah. You haven't initialized a value for 'mutable'. 
Lucky for you I can initialize it for you now.
[1] 12
> mutable(a)
[1] 12
>
> inMutable(a)
Hmmm, you haven't initialized a value for 'inMutable'. 
I'm afraid I can't do anything about that now.
NULL
> inMutable(a) <- 18
> inMutable(a)
[1] 18
>