根据文件
通过检查解析树的每个组件进行替换,如下所示:如果它不是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
。为什么?
答案 0 :(得分:1)
在访问该参数之前,没有与之关联的值 诺言。访问参数时,存储的表达式为 在存储的环境中进行评估,并返回结果。该 结果也是由诺言保存的。替代功能会 提取表达式槽的内容。这允许程序员 访问值或与表达式相关联的表达式 的承诺。
即使已经评估了表达式,承诺也会保留承诺。你可以看看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。这就是你上一次职能中发生的事情。