在下面的代码中,我期望f和最后的a都返回3。但实际上它们都返回2。为什么会这样呢?在评估promise时,3不是在封闭环境中替换了2吗?
a <- 1
f <- function(a){
a <<- 3
cat(a)
}
f(a <- 2)
a请注意,如果我在对f的调用中使用an =而不是a <-,则最终的a如预期的那样是3,但f仍然是2。
发布于 2018-02-07 23:36:52
让我们遍历代码
a <- 1 将值1指定给全局环境中的名称a。
f <- function(a){...}在全局环境中创建以f名称保存的函数。
f(a <- 2)现在,我们使用表达式a<-2作为参数调用函数f。此表达式不会立即求值。它是作为一个承诺通过的。a的全局值仍为1。
现在我们进入函数f的主体。我们传入的表达式被赋值给函数作用域中的局部变量a (仍未求值),而全局作用域中的a保持为1。它们都涉及符号a这一事实是不相关的。在这里,两个a变量之间没有直接联系。
a <<- 3这会通过<<-将值3赋给父作用域中的a,而不是像<-那样赋值给本地作用域。这意味着这里引用的a不是保存传递给函数的参数的本地a。因此,这会将全局作用域中的a值更改为3。
cat(a)现在,我们终于使用了传递给函数的值,因为这里的a引用了本地函数作用域中的a。这将触发promise a <- 2在调用作用域(恰好是全局作用域)中运行。因此,a的全局值被设置为2。此赋值表达式返回右侧的值,因此在cat()中显示"2“。
该函数将退出并
a显示了现在为a的全局环境中a的值。在f中,这只是两个表达式之间的短暂时刻的值3。
如果你在哪里打电话
f( a=2 )这是非常不同的。现在我们不再将表达式传递给函数,而是将值2传递给已命名的函数参数a。如果你尝试f(x=2),你会得到一个错误,即函数不能识别名为"x“的参数。因为2是一个常量,所以在这个场景中没有奇特的惰性表达式/promise求值。这将在函数调用后将全局值设置为3。f(a <- 2)和f(a = a <- 2)的行为方式是一样的。
https://stackoverflow.com/questions/48651792
复制相似问题