我试图研究如何在R中使用tryCatch()。我遇到了this tutorial,它提供了tryCatch()语法的最小示例:
红色箭头指出了我关心的问题:为了防止内存泄漏,我们是否必须在tryCatch()函数中显式删除在交替计算的表达式中分配的变量?还是调用垃圾收集器gc()?还是会以某种方式自动完成? (如果是这样,那么finally = { }
“的意义是什么?)
例如,我必须在# clean-up code??
行的地方键入什么?
result <- tryCatch({
a <- "Try this" # expression to try
}, warning=function(war){
b <- "Warning" # expression to deal with warning
}, error=function(err){
c <- "Error" # expression to deal with error
}, finally={
# cleanup code ??
})
最佳答案
R具有垃圾回收器,因此通常不必担心防止内存泄漏或显式运行垃圾回收器-这项工作已为您完成。当没有符号引用内存时,垃圾收集器将回收内存。由于tryCatch()
主体中的符号仍在范围内,因此它们不符合finally
子句中的收集条件。另一方面,错误处理程序中引用的符号不再在范围内,因此符合垃圾收集器的条件。但是无论如何,它们将有资格在下次R需要内存时进行收集,因此显式调用垃圾回收器没有任何值(value)。
在下面的示例中,有趣的是finally
的值未捕获,因此finally
纯粹是出于其副作用使用。例如,如果表达式是打开文件或数据库连接,则可能要使用finally
(这不是必需的!),并且希望确保无论是否发生错误都将其关闭(另请参见on.exit()
)。
这是一个示例,用于说明tryCatch()
的不同组件。
fun <- function(n) {
tries <- successes <- 0
for (i in seq_len(n)) {
result <- tryCatch({
if (rnorm(1) < 0)
stop("oops")
successes <- successes + 1
}, error=function(e) {
NULL # suppress errors
}, finally={
tries <- tries + 1
})
message(if (is.null(result)) "NULL" else result)
}
c(tries=tries, successes=successes)
}
fun()
采用参数n
,该参数表示执行for
循环主体的次数。每次通过循环,R都会生成随机法线偏差。如果偏差小于0(大约是时间的1/2),则会生成错误,并且错误处理程序
err=function(e) {...}
会抑制该错误-用户看不到错误消息,并且迭代继续进行。如果偏差大于或等于零,那么变量
successes
将增加1。无论是否生成错误,都会评估
finally={}
表达式并使tries
的值递增。tryCatch()
捕获result
语句的返回。如果发生错误,则result
是错误处理程序的值(NULL)。如果没有发生错误,则result
是tryCatch()
-successes + 1
评估的表达式的最后一行的值。该函数将打印出进度,并返回尝试和成功的命名 vector :
> fun_result <- fun(5)
1
NULL
2
NULL
3
> fun_result
tries successes
5 3
关于r - 垃圾收集器会在tryCatch语句的替代表达式中释放变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40621679/