首页 > 解决方案 > R中函数内'='和'<-'的范围顺序

问题描述

我试图了解 R 如何在函数内定义变量。为什么输出是 12?为什么不是4?a & b 这里是怎么分配的

我正在学习 R。请用一些参考资料解释

f1 <- function(a = {b <- 10; 2}, b = 2) {
  a+b
}

f1()

标签: r

解决方案


在 R 语言手册的第 4.3.3 节中有解释。

当一个函数被调用时,每个形式参数都会在调用的本地环境中分配一个 promise,表达式槽包含实际参数(如果存在)和环境槽包含调用者的环境。如果在调用中没有给出形式参数的实际参数并且存在默认表达式,则类似地将其分配给形式参数的表达式槽,但环境设置为本地环境。

通过评估 Promise 环境中表达式槽的内容来填充 Promise 的值槽的过程称为强制 Promise。一个promise 只会被强制执行一次,值槽内容稍后会直接使用。

在总和开始计算之前,没有任何价值。Firsta是必需的,因此它的表达式被评估。的承诺b丢失了,因为它在强制执行期间直接分配了一个值,因此根本不评估函数定义中a的实际分配承诺。b

如果顺序相反,您会看到不同的结果:

f2 <- function(a = 2, b = {a <- 10; 2}) {
  a+b
}

f2()
[1] 4

但是,请注意,a在函数结束时的值将是 10,但在求和期间需要它时为 2。这两个承诺都在这里得到评估。

如果总和的顺序相反,f1b+a会发现与 类似的行为f2

在该部分的前面有一个一般性的警告,即在作业中应避免副作用,因为它们不能保证它们会被评估。

R 有一种对函数参数的惰性求值形式。直到需要时才评估参数。重要的是要意识到在某些情况下,永远不会评估论点。因此,使用函数的参数来引起副作用是不好的风格。虽然在 C 中通常使用 foo(x = y) 形式来调用具有 y 值的 foo 并同时将 y 的值分配给 x,但在 R 中不应该使用这种相同的样式。不能保证该参数将永远被评估,因此分配可能不会发生。


推荐阅读