检查R的承诺是如何运作的,我认识到了一个我无法解释的效果。请考虑以下代码:
twice3 <- function(i) {
eval.subst <- function() eval(substitute(i))
print("one")
substitute(i)
print("two")
eval(substitute(i))
print("three")
eval(substitute(i))
print("four")
eval.subst()
print("five")
eval.subst()
}
这应该测试在我尝试评估promise中的表达式时发生的各种事情,而不强制承诺本身。这就是我得到的:
> twice3({print("hi"); 10})
[1] "one"
[1] "two"
[1] "hi"
[1] "three"
[1] "hi"
[1] "four"
[1] "hi"
[1] "five"
[1] 10
观察:
substitute
不评估或强迫任何事情。eval(substitute(i))
也没有强制原先的承诺,这是我所期待的。它可能会得到表达式并对其进行求值,而不会触及i
的值部分。eval.subst
应该与eval(substitute(i))
做同样的事情, 显示一些意外的缓存。起初,我认为只关注它的回报值,但是...... "five"
之后看到的那样,eval.subst
的调用已经评估了i
。 为什么最后一次效果会发生?我可以解释的唯一方法是在eval.subst
内,i
指的是封闭的东西,而不是“直接”到外部i
;但无论如何,如果我先替换,为什么会改变呢?
TL; DR 这里有什么区别:
> f1 <- function(i) {
+ eval.subst <- function() eval(substitute(i))
+ print('one')
+ eval.subst()
+ print('two')
+ i
+ }
> f1({print('hi'); 10})
[1] "one"
[1] "hi"
[1] "two"
[1] 10
> f2 <- function(i) {
+ print('one')
+ eval(substitute(i))
+ print('two')
+ i
+ }
> f2({print('hi'); 10})
[1] "one"
[1] "hi"
[1] "two"
[1] "hi"
[1] 10