R:存储在内存中的函数的形式在哪里?

时间:2018-04-29 11:13:25

标签: r scope arguments function-definition

当一个函数已经定义但尚未被调用时,是否存在没有默认值的形式?如果有,它们是存在于执行环境中,还是存在于函数定义所在的环境中,还是存在于其他地方?

如果已定义某个函数但尚未调用,并且已为正式分配了一个默认值,那么该值是否存在?如果是,它在什么环境中存在?如果默认表达式求值为常量,是否已将形式赋值给该值,则在调用函数时如果提供了值,则会被覆盖?如果不是,在什么环境中(固定的)默认值位于定义时刻和调用函数的时间之间?

在调用函数并将实际值或默认值分配给正式函数后,传递到正文中,如果需要作用域和/或评估,是否继续存在形式?如果是这样,那么它们在什么环境中存在呢?

1 个答案:

答案 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()环境中对象的详细演练。

关于形式在内存中存在多长时间的问题,只要创建用于存储函数的被调用实例的环境在内存中,它们就存在。由于垃圾收集器对没有外部引用的对象进行操作,因此如果函数实例未保存到对象,则只要函数调用将结果返回到父环境,它就有资格进行垃圾回收。