为另一个函数中定义的函数使用相同的参数名称

时间:2021-10-10 23:57:17

Why does

f <- function(a) {
    g <- function(a=a) {
        return(a + 2)
    }
    return(g())
}
f(3)  # Error in a + 2: 'a' is missing

cause an error? It has something to do with the a=a argument, particularly with the fact that the variable names are the same. What exactly is going on?

导致错误?它与a = a参数有关,特别是与变量名相同的事实。到底发生了什么?

Here are some similar pieces of code that work as expected:

以下是一些按预期工作的类似代码:

f <- function(a) {
    g <- function(a) {
        return(a + 2)
    }
    return(g(a))
}
f(3)  # 5

f <- function(a) {
    g <- function(g_a=a) {
        return(g_a + 2)
    }
    return(g())
}
f(3)  # 5

g <- function(a) a + 2
f <- function(a) g(a)
f(3)  # 5

2 个解决方案

#1


6  

The problem is that, as explained in the R language definition:

问题是,正如R语言定义中所解释的那样:

The default arguments to a function are evaluated in the evaluation frame of the function.

函数的默认参数在函数的求值框架中计算。

In your first code block, when you call g() without any arguments, it falls back on its default value of a, which is a. Evaluating that in the "frame of the function" (i.e. the environment created by the call to g()), it finds an argument whose name matches the symbol a, and its value is a. When it looks for the value of that a, it finds an argument whose name matches that symbol, and whose value is a. When...

在你的第一个代码块中,当你在没有任何参数的情况下调用g()时,它会回退到它的默认值a,即a。在“函数的框架”(即通过调用g()创建的环境)中评估它,它找到一个名称与符号a匹配的参数,其值为a。当它查找该值的值时,它会找到一个名称与该符号匹配的参数,其值为a。什么时候...

As you can see, you're stuck in a loop, which is what the error message is trying to tell you:

正如您所看到的,您陷入了循环,这是错误消息试图告诉您的:

Error in g() : 
  promise already under evaluation: recursive default argument reference or 
earlier problems?

Your second attempt, which calls g(a) works as you expected, because you've supplied an argument, and, as explained in the same section of R-lang:

你的第二次尝试,调用g(a)按预期工作,因为你提供了一个参数,并且如R-lang的相同部分所述:

The supplied arguments to a function are evaluated in the evaluation frame of the calling function.

在调用函数的求值框架中计算提供的函数参数。

There it finds a symbol a, which is bound to whatever value you passed in to the outer function's formal argument a, and all is well.

在那里它找到一个符号a,它绑定到你传递给外部函数的形式参数a的任何值,一切都很好。

#2


4  

The problem is the a=a part. An argument can't be its own default. That is a circular reference.

问题是a = a部分。参数不能是它自己的默认值。这是一个循环参考。

This example may help clarify how it works:

此示例可能有助于阐明其工作原理:

x <- 1
f <- function(a = x) { x <- 2; a }
f()
## [1] 2

Note that a does not have the default 1; it has the default 2. It looks first in the function itself for the default. In a similar way a=a would cause a to be its own default which is circular.

请注意,a没有默认值1;它具有默认值2.它首先在函数本身中查找默认值。以类似的方式,a = a将导致a成为其自己的默认值,即圆形。

#1


6  

The problem is that, as explained in the R language definition:

问题是,正如R语言定义中所解释的那样:

The default arguments to a function are evaluated in the evaluation frame of the function.

函数的默认参数在函数的求值框架中计算。

In your first code block, when you call g() without any arguments, it falls back on its default value of a, which is a. Evaluating that in the "frame of the function" (i.e. the environment created by the call to g()), it finds an argument whose name matches the symbol a, and its value is a. When it looks for the value of that a, it finds an argument whose name matches that symbol, and whose value is a. When...

在你的第一个代码块中,当你在没有任何参数的情况下调用g()时,它会回退到它的默认值a,即a。在“函数的框架”(即通过调用g()创建的环境)中评估它,它找到一个名称与符号a匹配的参数,其值为a。当它查找该值的值时,它会找到一个名称与该符号匹配的参数,其值为a。什么时候...

As you can see, you're stuck in a loop, which is what the error message is trying to tell you:

正如您所看到的,您陷入了循环,这是错误消息试图告诉您的:

Error in g() : 
  promise already under evaluation: recursive default argument reference or 
earlier problems?

Your second attempt, which calls g(a) works as you expected, because you've supplied an argument, and, as explained in the same section of R-lang:

你的第二次尝试,调用g(a)按预期工作,因为你提供了一个参数,并且如R-lang的相同部分所述:

The supplied arguments to a function are evaluated in the evaluation frame of the calling function.

在调用函数的求值框架中计算提供的函数参数。

There it finds a symbol a, which is bound to whatever value you passed in to the outer function's formal argument a, and all is well.

在那里它找到一个符号a,它绑定到你传递给外部函数的形式参数a的任何值,一切都很好。

#2


4  

The problem is the a=a part. An argument can't be its own default. That is a circular reference.

问题是a = a部分。参数不能是它自己的默认值。这是一个循环参考。

This example may help clarify how it works:

此示例可能有助于阐明其工作原理:

x <- 1
f <- function(a = x) { x <- 2; a }
f()
## [1] 2

Note that a does not have the default 1; it has the default 2. It looks first in the function itself for the default. In a similar way a=a would cause a to be its own default which is circular.

请注意,a没有默认值1;它具有默认值2.它首先在函数本身中查找默认值。以类似的方式,a = a将导致a成为其自己的默认值,即圆形。