R中这个函数的逻辑是什么?

What is the logic of this function in R?

我正在研究 R 函数中的参数,但我在理解它的逻辑时遇到了一些问题。

h <- function(a = 1, b = d){
    d <- (a + 1)^2
    c(a, b)
}

h()
# [1] 1 4

我预计错误消息会是 return,因为 b 没有值。 d 是在 h 函数下创建的,但没有像 b = d 这样的代码在函数 h 中为 b 赋值。

然而,结果是[1] 1 4

bd 是如何关联的?

默认函数参数值在 R 中延迟求值(即仅在需要时求值):

查看此代码的输出示例:

printme <- function(name,x){cat('evaluating',name,'\n');x}

h <- function(a = printme('a',1), b = printme('b',d)){
  cat('computing d...\n')
  d <- (a + 1)^2
  cat('d computed\n')
  cat('concatenating a and b...\n')
  c(a, b)
  cat('a and b concatenated\n')
}

h()

控制台输出:

computing d...
evaluating a 
d computed
concatenating a and b...
evaluating b 
a and b concatenated

可以看到,d是在评估默认值b

之前计算的

编辑:

此外,正如 @BrodieG 在评论中正确指出的那样,默认参数是在函数环境中求值的;实际上,在上面的示例中,b 可以初始化为函数环境中定义的变量 d 的值。

相反,当您指定一个参数(不使用默认值)时,分配参数的表达式仍然被延迟计算,但这次是在调用环境中,例如:

# same functions as above, but this time we specify the parameters in the call     
h(a=printme('a',123),b=printme('d',d))

控制台输出:

computing d...
evaluating a 
d computed
concatenating a and b...
evaluating d 
Error in printme("d", d) : object 'd' not found

注意参数 b 求值时的错误,因为在调用环境中找不到 d