【问题标题】:call return from child frame从子框架调用返回
【发布时间】:2025-12-03 20:55:02
【问题描述】:

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

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 并返回1,如果second_try 有效,它将返回2

这样的事情可能吗?

【问题讨论】:

  • 我不确定我是否正确理解了这个问题。如果您想返回first_try,为什么需要second_try3。如果返回值取决于别的东西,为什么不使用if-else
  • 3 只是表明first_trysecond_try 都不起作用。实际上这个函数会被包装成一个条件,所以后面会有代码,这里缩写为3。这样更清楚吗?
  • 如果是这样,为什么不试试if(a){return(1)}else if(b){return(2)}; 3;
  • 这是一个可读性、编程便利性和好奇心的问题,我并没有被困在我的工作中。我有一个函数,它总是会跟随或嵌入一个返回调用,所以将返回调用放在里面对我来说是有意义的。

标签: r return eval r-environment


【解决方案1】:

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() 是函数 base::eval() 的低级版本。 从技术上讲,它是 C 函数 Rf_eval() 的简单包装器。 您通常不需要使用 eval_bare() 来代替 eval()。它的 主要优点是它处理堆栈敏感(调用如 return()、on.exit() 或 parent.frame()) 在您通过时更加一致 调用堆栈上的框架环境。

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-01-03 创建

【讨论】: