R语言tryCatch块内赋值无法传递到外部环境问题咨询
问题产生原因
这个现象是R的作用域规则导致的:
- 你在
tryCatch传入的error、warning处理函数内部,用<-给ret赋值时,修改的是处理函数独立运行环境内的局部变量,和你在全局环境最开始定义的ret不是同一个变量。 - 函数内部的局部赋值默认不会改动父级环境(也就是你的代码运行的全局环境)的同名变量,所以全局环境里的
ret从头到尾都保持初始值0,哪怕已经触发了error分支的日志打印,外部的ret也不会被内部的赋值操作修改。
修正方法
你可以选以下两种常用方案实现需求,第二种写法更规范,推荐优先使用:
方案1:使用超赋值运算符修改全局变量
把处理函数内部的<-替换为<<-,这个运算符会沿着环境层级向上查找同名变量并赋值,直接修改全局环境的ret:
ret <- 0 tryCatch(expr = { cat(non_existing_variable, "\n") }, error = function(e) { ret <<- 1 cat("Got into error condition!\n") }, warning = function(w) { ret <<- 2 cat("Got into warning condition!\n") } ) cat("ret =", ret, "\n")
运行后输出ret = 1,符合预期。
方案2:直接接收tryCatch的返回值(推荐)
tryCatch本身会返回当前执行分支的最后一个表达式的结果,你不需要提前初始化全局变量再跨环境修改,直接把tryCatch的运行结果赋值给ret即可,逻辑更清晰也不会出现作用域问题:
ret <- tryCatch(expr = { cat(non_existing_variable, "\n") 0 # 正常执行完成返回状态码0 }, error = function(e) { cat("Got into error condition!\n") 1 # 触发错误返回状态码1 }, warning = function(w) { cat("Got into warning condition!\n") 2 # 触发警告返回状态码2 } ) cat("ret =", ret, "\n")
内容的提问来源于stack exchange,提问作者Mefitico
相关产品推荐
相关产品推荐

