当一个函数已经定义但尚未被调用时,是否存在没有默认值的形式?如果有,它们是存在于执行环境中,还是存在于函数定义所在的环境中,还是存在于其他地方?
如果已定义某个函数但尚未调用,并且已为正式分配了一个默认值,那么该值是否存在?如果是,它在什么环境中存在?如果默认表达式求值为常量,是否已将形式赋值给该值,则在调用函数时如果提供了值,则会被覆盖?如果不是,在什么环境中(固定的)默认值位于定义时刻和调用函数的时间之间?
在调用函数并将实际值或默认值分配给正式函数后,传递到正文中,如果需要作用域和/或评估,是否继续存在形式?如果是这样,那么它们在什么环境中存在呢?
答案 0 :(得分:4)
一旦函数的一个实例通过被调用加载到内存中,函数的形式就作为函数环境中的对象存在。在 Advanced R 中,Hadley Wickham将此环境称为execution environment。可以通过pryr::address()
访问对象的内存位置。
作为一个例子,我将使用我之前编写的代码的修改版本来说明makeVector()
函数中的约翰霍普金斯R Programming课程的第二个编程作业中的内存位置{ {3}}。
makeVector <- function(x = 200) {
library(pryr)
message(paste("Address of x argument is:",address(x)))
message(paste("Number of references to x is:",refs(x)))
m <- NULL
set <- function(y) {
x <<- y
message(paste("set() address of x is:",address(x)))
message(paste("Number of references to x is:",refs(x)))
m <<- NULL
}
get <- function() x
setmean <- function(mean) m <<- mean
getmean <- function() m
list(set = set, get = get,
setmean = setmean,
getmean = getmean)
}
如上所述,makeVector()
是一个S3对象,这意味着我们可以通过getter和setter(也称为coursera.org)访问其环境中的对象。
我们可以将makeVector()
对象的实例加载到内存中,并使用以下代码查询x
的地址和值。
makeVector()$get()
......结果:
> makeVector()$get()
Address of x argument is: 0x1103df4e0
Number of references to x is: 0
[1] 200
>
正如我们从输出中看到的那样,x
确实有一个内存位置,但是没有其他对象包含对它的引用。此外,x
设置为长度为1的向量的默认值,值为200.
我在mutator methods的答案中提供了makeVector()
环境中对象的详细演练。
关于形式在内存中存在多长时间的问题,只要创建用于存储函数的被调用实例的环境在内存中,它们就存在。由于垃圾收集器对没有外部引用的对象进行操作,因此如果函数实例未保存到对象,则只要函数调用将结果返回到父环境,它就有资格进行垃圾回收。