【发布时间】:2017-08-14 07:10:22
【问题描述】:
根据文档
通过检查解析树的每个组件来进行替换,如下所示:如果它不是 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。为什么?
【问题讨论】:
-
x和force(x)在第二种和第三种情况下没有分配。因此,substitute(x)在两种情况下都作为x的原始值返回,即a -
如果分配了
force(x),例如f1 <-function(x){tmp <- force(x); substitute(tmp)}然后f1(a)将返回值10 -
来自语言定义:“在访问该参数之前,没有与承诺相关联的值。访问参数时,存储的表达式在存储的环境中进行评估,并返回结果。结果也由 promise 保存。替代函数将提取表达式槽的内容。这允许程序员访问与 promise 关联的值或表达式。即使它的表达式已经被评估,一个 Promise 仍然是一个 Promise。
-
@AdamQuek 我同意这与是否分配
x有关。但是substitute是如何检测到x被分配的呢?如果您使用ls.str(environment()),您可以看到x已经绑定到10。 -
@Roland 我明白了。因此,除非 promise
x被局部变量“x”覆盖,否则无论它是否被评估,它都将保持一个 promise。
标签: r