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

为什么R语言中未使用!!运算符时glue无法找到fun_C_notok中的x变量

问题原因

这个问题的核心是glue的变量查找逻辑和rlang非标准求值带来的环境错位共同导致的,具体可以拆解为三点:

  1. 你看到list(...)可以正常打印x、y的值是正常的,因为list()会强制求值所有传入...的参数,不管参数的绑定环境是什么,都能拿到实际值。
  2. 但glue的变量查找逻辑不同:它会优先把...里的参数放到一个临时求值环境,再把该环境的父环境设为你传入的.envir(默认是调用glue时的父环境,也就是fun_A的调用环境)。当你在fun_B里用rlang::enquo()捕获fun_A的调用表达式、再用eval_tidy()执行时,fun_A的调用环境是rlang创建的临时mask环境,这个环境里没有x、y变量,而glue在eval_tidy的上下文中无法正确读取...里的变量,才会报找不到对象的错误。
  3. 加了!!运算符后能正常运行的原因也很简单:!!是rlang的即时求值运算符,会在enquo捕获fun_A调用表达式的阶段,就把x、y的实际值注入到表达式里,这时候传入fun_A的x、y不再是指向fun_C_notok环境的变量引用,而是固定的常量值,glue就可以正常识别匹配了。
可选解决方案

如果你不想每次调用都写!!,可以直接修改fun_A的实现,两种修改方式都可以:

  • 显式指定glue的求值环境为fun_A的当前执行环境:
fun_A <- function(my_string, ..., z = NULL){
  print(paste0("z value: ", as.character(z)))
  print(list(...))
  # 新增.envir参数指定为当前环境
  my_string <- glue::glue(my_string, ..., .envir = environment())
  return(my_string)
}
  • 先把...强制求值为列表,再用!!!展开传入glue:
fun_A <- function(my_string, ..., z = NULL){
  print(paste0("z value: ", as.character(z)))
  dots <- list(...)
  print(dots)
  # 强制求值后展开传入
  my_string <- glue::glue(my_string, !!!dots)
  return(my_string)
}

以上两种修改方式都可以让fun_C_notok不加!!也能正常运行。

内容的提问来源于stack exchange,提问作者Damien Debot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:36:07