R:使用泛型方法修改现有S3对象的属性



假设我有一个具有两个属性的类的构造函数,其中一个属性已启动,另一个属性设置为NULL:

myclass <- function(data) {
structure(
list(data1 = data,
data2 = NULL),
class = "myclass")
}

和一个通用:

myadd <- function(obj, x) {
UseMethod("myadd")
}
myadd.myclass <- function(obj, x) {
obj$data2 = obj$data1 + x
}

当我这样做时:

mc = myclass(1)
myadd(mc, 2)

属性data2不变:

> mc
$data1
[1] 1
$data2
NULL
attr(,"class")
[1] "myclass"

显然,当我将结果分配给一个变量时:

tmp = myadd(mc, 2)

我得到的结果:

> tmp
[1] 3

如何使用泛型函数修改现有对象的属性?这样做是犹太洁食吗?

我想我错过了一些关于R中S3类或OOP的关键信息。任何提示都将不胜感激。

1(将其传回R在尝试修改函数时复制obj。原始obj不会更改。其思想是R是一种函数语言,可以最大限度地减少副作用。

将其传递回调用者,并将其分配给调用者。

myadd.myclass <- function(obj, x) {
obj$data2 = obj$data1 + x
obj
}
mc <- myclass(1)
mc <- myadd(mc, 2)
mc
## $data1
## [1] 1
##
## $data2
## [1] 3
##
## attr(,"class")
## [1] "myclass"

2(替换方法另一种可能性是定义替换函数:

"myadd<-" <- function(x, ..., value) UseMethod("myadd<-")
"myadd<-.myclass" <- function(x, ..., value) { x$data2 <- x$data1 + value; x }
mc <- myclass(1)
myadd(mc) <- 2
mc
## $data1
## [1] 1
##
## $data2
## [1] 3
##
## attr(,"class")
## [1] "myclass"

3(环境还有一种方法是使用环境而不是列表。

myclass <- function(data) {
structure(local({
data1 = data
data2 = NULL
environment()
}), class = c("myclass", "environment"))
}
# next two functions are same as in question
myadd <- function(obj, x) UseMethod("myadd")
myadd.myclass <- function(obj, x) obj$data2 = obj$data1 + x
obj <- myclass(1)
myadd(obj, 2)
as.list(obj)
## $data1
## [1] 1
##
## $data2
## [1] 3

最新更新