包中的全局变量 - 更推荐哪种方法?
Global variable in a package - which approach is more recommended?
我知道全局变量通常是有害的,我应该避免使用它们,但是如果我的包确实需要一个全局变量,这两种方法中哪一种更好?还有其他推荐的方法吗?
使用包可见的环境
pkgEnv <- new.env()
pkgEnv$sessionId <- "xyz123"
使用options
options("pkgEnv.sessionId" = "xyz123")
我知道还有其他一些帖子在问如何实现全局变量,但是我没有看到推荐使用哪一个的讨论
当大多数人说您应该避免 'global' 变量时,他们的意思是您不应该分配给全局环境(.GlobalEnv
、GlobalEnv
或 as.environment(1)
)或除了将此类数据作为函数调用的参数传递之外,您不应通过任何方法在内部函数之间传递信息。
缓存完全是另一回事。我经常缓存不想重新计算(记忆)或重新查询的结果。我在包中经常使用的模式如下:
myFunction <- local({
cache <- list() # or numeric(0) or whatever
function(x,y,z){
# calculate the index of the answer
# (most of the time this is a trivial calculation, often the identity function)
indx = answerIndex(x,y,z)
# check if the answer is stored in the cache
if(indx %in% names(cacheList))
# if so, return the answer
return(cacheList[indx])
[otherwise, do lots of calculations or data queries]
# store the answer
cahceList[indx] <<- answer
return(answer)
}
})
对 local
的调用创建了一个新环境,我可以在其中使用作用域赋值运算符 <<-
存储结果,而不必担心包已经密封,最后一个表达式(函数定义)作为调用 local()
的值返回并绑定到名称 myFunction
.
有些包使用隐藏变量(以 .
开头的变量),例如 .Random.seed
和 .Last.value
在 base R 中使用。在你的包中你可以做
e <- new.env()
assign(".sessionId", "xyz123", envir = e)
ls(e)
# character(0)
ls(e, all = TRUE)
# [1] ".sessionId"
但是在你的包中你不需要分配e
。您可以使用 .onLoad()
挂钩在加载包时分配变量。
.onLoad <- function(libname, pkgname) {
assign(".sessionId", "xyz123", envir = parent.env(environment()))
}
请参阅 this question 及其答案,了解有关包变量的一些很好的解释。
我知道全局变量通常是有害的,我应该避免使用它们,但是如果我的包确实需要一个全局变量,这两种方法中哪一种更好?还有其他推荐的方法吗?
使用包可见的环境
pkgEnv <- new.env() pkgEnv$sessionId <- "xyz123"
使用
options
options("pkgEnv.sessionId" = "xyz123")
我知道还有其他一些帖子在问如何实现全局变量,但是我没有看到推荐使用哪一个的讨论
当大多数人说您应该避免 'global' 变量时,他们的意思是您不应该分配给全局环境(.GlobalEnv
、GlobalEnv
或 as.environment(1)
)或除了将此类数据作为函数调用的参数传递之外,您不应通过任何方法在内部函数之间传递信息。
缓存完全是另一回事。我经常缓存不想重新计算(记忆)或重新查询的结果。我在包中经常使用的模式如下:
myFunction <- local({
cache <- list() # or numeric(0) or whatever
function(x,y,z){
# calculate the index of the answer
# (most of the time this is a trivial calculation, often the identity function)
indx = answerIndex(x,y,z)
# check if the answer is stored in the cache
if(indx %in% names(cacheList))
# if so, return the answer
return(cacheList[indx])
[otherwise, do lots of calculations or data queries]
# store the answer
cahceList[indx] <<- answer
return(answer)
}
})
对 local
的调用创建了一个新环境,我可以在其中使用作用域赋值运算符 <<-
存储结果,而不必担心包已经密封,最后一个表达式(函数定义)作为调用 local()
的值返回并绑定到名称 myFunction
.
有些包使用隐藏变量(以 .
开头的变量),例如 .Random.seed
和 .Last.value
在 base R 中使用。在你的包中你可以做
e <- new.env()
assign(".sessionId", "xyz123", envir = e)
ls(e)
# character(0)
ls(e, all = TRUE)
# [1] ".sessionId"
但是在你的包中你不需要分配e
。您可以使用 .onLoad()
挂钩在加载包时分配变量。
.onLoad <- function(libname, pkgname) {
assign(".sessionId", "xyz123", envir = parent.env(environment()))
}
请参阅 this question 及其答案,了解有关包变量的一些很好的解释。