请考虑以下代码:
test1 <- "a"
test2 <- "a"
tryCatch(stop(), error= function(err){
print(test1)
print(test2)
test1 <- "b"
test2 <<- "b"
})
结果:
print(test1)
[1] "a"
print(test2)
[1] "b"
变量test1的值在tryCatch块中可见,但是用&#34;&lt; - &#34;运算符不会影响tryCatch块之外的值。
如果使用&lt;&lt; - 指定了新值,则它具有所需的效果。为什么呢?
在tryCatch块中使用&lt;&lt; - 运算符是一种推荐的方法来更改此块外部的局部变量的值吗?可能有一些意想不到的副作用吗?
编辑:根据Bernhard的回答,以下代码是否弥补了解决此问题的正确方法?
test1 <- "a"
test2 <- "a"
new_values<-tryCatch(
{
print("hello")
stop()
}
, error= function(err){
# I want to change the test1 and test 2 variables to "b" only if error occurred.
test1 <- "b"
test2 <- "b"
return(list(test1=test1,test2=test2))
})
if (is.list(new_values))
{
test1<-new_values$test1
test2<-new_values$test2
}
结果:
> print(test1)
[1] "b"
> print(test2)
[1] "b"
答案 0 :(得分:4)
'&lt;&lt;&lt; - '用于不属于R的副作用。永远使用它,或者仅在内存或速度迫使你这样做时使用它。一个块有它自己的范围,如果你想将一个块内的数据提供给'外部'环境,那么该任务有return():
test2 <- "a"
test2 <- tryCatch(stop(), error= function(err){
somevariable <- "b"
return(somevariable)
})
这让每个人都清楚,toplevel test2被设置为“a”然后,toplevel test2被设置为其他东西。使用'&lt;&lt; - ',它很容易发生,有些函数更改为toprevel test2而有人想知道,为什么toplevel test2已经完全改变了。只是不要&lt;&lt; - 。
如果需要返回多个结果,请返回结果的列表或对象。
编辑:OP指出你需要小心返回语句,因为它们不仅结束当前块,还结束当前函数。一种可能的解决方案是,在函数中运行计算而不是简单的块。以下示例应说明这一点:
safediv <- function(a, b){
normalDo <- function(a, b){
return(list(value=a/b, message=NULL))
}
exceptionalDo <- function(err){
return(list(value=NaN, message="caught an error! Change global variable?"))
}
results <- tryCatch(normalDo(a, b), error=exceptionalDo)
print("safediv is still running after the returns within the functions.")
return(results)
}
# try it out
safediv(5, 3)
safediv(5, 0)
safediv(5, "a")