r - 在函数中添加全局 S3 对象的类,避免使用 `<<-` 运算符
问题描述
我在函数内定义一个 S3 对象并将其分配给全局环境中的变量;随后在同一个函数中,我向它添加了一个额外的类。我能够做到这一点的唯一方法是使用<<-
运算符,我宁愿避免在阅读时它实际上分配给父环境,这可能很危险。理想情况下,我想使用assign
,但第一个参数是变量名,所以它失败了。关于如何在不使用的情况下更好地实现这一点的任何建议<<-
?
作为记录,我也尝试了正常的赋值运算符<-
,但这也失败了,不明白为什么,因为变量已经在全局范围内定义。
下面的一些说明性示例:
# <<- assigns to parent environment, if "lucky" that is the globalenv, me no gusto :(
foo_works_dragons <- function(addclass) {
fooobj <- structure(list(), class = "Alpha")
assign("G_FOOOBJ", fooobj, envir = globalenv())
class(G_FOOOBJ) <<- c(class(G_FOOOBJ), addclass)
return(TRUE)
}
# prefer assign statement but function argument x is "a variable name" from man page, so ok not working, any suggestions?
foo_fails_nodragons <- function(addclass) {
fooobj <- structure(list(), class = "Alpha")
assign("G_FOOOBJ", fooobj, envir = globalenv())
assign("class(G_FOOOBJ)", c(class(G_FOOOBJ), addclass), envir = globalenv())
return(TRUE)
}
# fails, don't understand though why
foo_fails_but_why <- function(addclass) {
fooobj <- structure(list(), class = "Alpha")
assign("G_FOOOBJ", fooobj, envir = globalenv())
class(G_FOOOBJ) <- c(class(G_FOOOBJ), addclass)
return(TRUE)
}
foo_works_dragons("Beta")
print(class(G_FOOOBJ))
# [1] "Alpha" "Beta"
rm(G_FOOOBJ)
foo_fails_nodragons("Beta")
print(class(G_FOOOBJ))
# [1] "Alpha"
rm(G_FOOOBJ)
foo_fails_but_why("Beta")
print(class(G_FOOOBJ))
# [1] "Alpha"
rm(G_FOOOBJ)
解决方案
使用 envir$object 表示法:
foo <- function(addclass, envir = .GlobalEnv) {
envir$G_FOOOBJ <- structure(list(), class = "Alpha")
class(envir$G_FOOOBJ) <- c(class(envir$G_FOOOBJ), addclass)
return(TRUE)
}
if (exists("G_FOOOBJ")) rm(G_FOOOBJ)
foo("Beta")
## [1] TRUE
G_FOOOBJ
## list()
## attr(,"class")
## [1] "Alpha" "Beta"
如果你真的想使用,assign
那么这个工作:
foo2 <- function(addclass, envir = .GlobalEnv) {
fooobj <- structure(list(), class = "Alpha")
assign("G_FOOOBJ", structure(fooobj, class = c(class(fooobj), addclass)), envir)
return(TRUE)
}
if (exists("G_FOOOBJ")) rm(G_FOOOBJ)
foo2("Beta")
## [1] TRUE
G_FOOOBJ
## list()
## attr(,"class")
## [1] "Alpha" "Beta"
推荐阅读
- reactjs - 道具未定义,但我可以看到它在控制台记录道具
- asp.net - jwt 验证期间的 Asp.net 核心缓存 jwk
- sql - 使用集群的 hive 子查询优化
- r - 如何为股票代码列表上的调整收盘价编写一个 for 循环?
- reactjs - React-router - 将当前路由设置为最后一个路由
- javascript - Firebase 函数 - admin.messaging().sendToTopic 执行但从未进入 `then` 块
- ios - Xcode 中的 IOS MapKit 出错:在捆绑包 NSBundle 中找不到名为“Main”的故事板
- javascript - HTMLCollection [] 未定义
- java - 在 Java 中强制转换为时间戳
- php - WordPress 中的博客文章作者过滤器