You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何函数名与参数名相同时,默认参数调用函数会报错?

函数名与参数名同名时默认参数调用失败的底层原因解析

当函数的参数名和外部函数名同名,且将该外部函数调用作为参数默认值时,会触发递归求值错误,先看报错的示例代码:

f1 <- function(){
  2
}

f2 <- function(f1 = f1()){
  f1 * 2
}

f2()
#> Error in f2(): promise already under evaluation: recursive default argument reference or earlier problems?

底层逻辑:R的Promise机制与作用域查找

R处理函数参数默认值时,会用到**Promise(延迟求值)**机制:参数不会在函数定义阶段立即计算,而是等到函数内部第一次调用该参数时才触发求值。

当执行f2()时,参数f1的默认值开始求值,过程如下:

  1. 要计算f1(),R会按作用域查找顺序寻找f1对象:先在f2的局部环境里查找,再去父环境(比如全局环境)查找。
  2. 此时f2的局部环境中已经存在一个名为f1的Promise对象(就是当前正在求值的参数),R会优先匹配这个Promise,而非全局环境里的f1函数。
  3. 但这个Promise本身正处于求值过程中,尝试调用它就会触发"promise already under evaluation"的递归引用错误。

修复方案的生效原理

修复方案1:重命名外部函数

f <- function(){
  2
}

f2 <- function(f1 = f()){
  f1 * 2
}

f2()
#> [1] 4

把全局环境的函数从f1改名为f后,计算默认值f()时,R在f2的局部环境里找不到f,就会去全局环境定位到f函数,正常执行调用,不会和参数f1产生冲突。

修复方案2:重命名函数参数

f1 <- function(){
  2
}

f2 <- function(.f1 = f1()){
  .f1 * 2
}

f2()
#> [1] 4

把f2的参数名改为.f1后,计算默认值f1()时,R在f2的局部环境里找不到名为f1的对象,就会去全局环境找到f1函数,顺利完成调用,参数.f1接收返回值2后即可正常计算。

内容的提问来源于stack exchange,提问作者Austin Graves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 12:31:02