替代品无法按预期工作

时间:2017-08-14 07:10:23

标签: r

根据文件

  

通过检查解析树的每个组件进行替换,如下所示:如果它不是env中的绑定符号,则不变。如果它是一个promise对象,即函数的形式参数或使用delayedAssign()显式创建的,则promise的表达式槽替换该符号。如果它是普通变量,则其值被替换,除非env是.GlobalEnv,在这种情况下符号保持不变。

所以我做了一些实验

a = 10

# first
f1 = function(x){
  substitute(x)
  }
f1(a)
# [1] a


# second
f1 = function(x){
  x
  substitute(x)
  }
f1(a)
# [1] a

# third
f1 = function(x){
  force(x)
  substitute(x)
  }
f1(a)
# [1] a

# fourth
f1 = function(x){
  x = x
  substitute(x)
  }
f1(a)
# [1] 10

在第二次和第三次实验中,我认为x不再是一个承诺,因此substitute应该返回10而不是a。但它仍然返回a。为什么?

1 个答案:

答案 0 :(得分:1)

来自language definition

  

在访问该参数之前,没有与之关联的值   诺言。访问参数时,存储的表达式为   在存储的环境中进行评估,并返回结果。该   结果也是由诺言保存的。替代功能会   提取表达式槽的内容。这允许程序员   访问值或与表达式相关联的表达式   的承诺。

即使已经评估了表达式,承诺也会保留承诺。你可以看看pryr包会发生什么:

library(pryr)
f=function(x){
  print(promise_info(x))
  force(x)
  promise_info(x)
}

a <- 10
f(a)

#$code
#a
#
#$env
#<environment: R_GlobalEnv>
#
#$evaled
#[1] FALSE
#
#$value
#NULL
############################
#$code
#a
#
#$env
#NULL
#
#$evaled
#[1] TRUE
#
#$value
#[1] 10

显然,为符号分配新值会使用该值替换promise。这就是你上一次职能中发生的事情。