首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >实现S3类的提取和赋值运算符的最佳方法

实现S3类的提取和赋值运算符的最佳方法
EN

Stack Overflow用户
提问于 2017-08-21 19:06:23
回答 1查看 45关注 0票数 1

假设我有一个foo类的类似列表的对象,并且我想为它实现赋值操作符。该类与普通列表的不同之处在于,每个元素都使用"bar_"前缀命名(这只是一个虚构的示例)。所以我对赋值操作符的简单实现是:

代码语言:javascript
代码运行次数:0
运行
复制
"[<-.foo" <- function(x, i, value) {
   x[paste0("bar_", i)] <- value
}

显然,这是行不通的,因为它进入了无限循环:

代码语言:javascript
代码运行次数:0
运行
复制
as.foo <- function(x) {
  names(x) <- paste0("bar_", names(x))
  class(x) <- c(class(x), "foo")
  x
}

x <- as.foo(list(a = 1, b = 2))
x["a"] <- 42
## Error: C stack usage  7970836 is too close to the limit

实现这种方法的最佳实践是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-21 19:28:28

子集/子分配函数是特殊的,因为在R级别上没有泛型方法,也没有默认方法。这些都是用C代码处理的。原因当然是性能: S3方法分派相对较慢,子集需要尽可能快,因为它使用得太多了。

我会暂时删除这个类:

代码语言:javascript
代码运行次数:0
运行
复制
"[<-.foo" <- function(x, i, value) {
  theclass <- class(x)
  class(x) <- class(x)[-inherits(x, "foo", TRUE)]
  x[paste0("bar_", i)] <- value
  class(x) <- theclass
  x
}

顺便说一句,我会重写as.foo

代码语言:javascript
代码运行次数:0
运行
复制
as.foo <- function(x) {
  stopifnot(is.list(x))
  names(x) <- paste0("bar_", names(x))
  class(x) <- c("foo", attr(x, "class"))
  x
}

这避免了向class属性添加隐式类。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45795521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档