从子框架调用 return

call return from child frame

如何通过另一个函数 return 一个函数中的值,请参见此处的示例:

first_try <- function() eval(return(1),parent.frame())
second_try <- function() source(textConnection("return(2)"),parent.frame())

fun1 <- function(x){
  first_try()
  second_try()
  3
}

fun1()
# [1] 3

fun1 应该在 first_try 和 return 1 处停止,如果 second_try 有效,它将 returned 2.

这样的事情可能吗?

rlang::return_from() 提供此功能:

return_a <- function() rlang::return_from(parent.frame(),"a")

fun <- function(){
  return_a()
  "b"
}
fun()
#> [1] "a"

reprex package (v0.3.0)

于 2020 年 1 月 3 日创建

我们也可以通过引用 return(1) 并使用 rlang::eval_bare() 而不是 base::eval()

来修复我的第一次尝试

来自文档:

eval_bare() is a lower-level version of function base::eval(). Technically, it is a simple wrapper around the C function Rf_eval(). You generally don't need to use eval_bare() instead of eval(). Its main advantage is that it handles stack-sensitive (calls such as return(), on.exit() or parent.frame()) more consistently when you pass an enviroment of a frame on the call stack.

first_try <- function() rlang::eval_bare(quote(return(1)),parent.frame())
fun1 <- function(x){
  first_try()
  second_try()
  3
}

fun1()
#> [1] 1

reprex package (v0.3.0)

于 2020 年 1 月 3 日创建