R: Где формалы для функции хранятся в памяти?
Когда функция была определена, но еще не была вызвана, существуют ли формалы, которые не имеют значений по умолчанию? Если они есть, существуют ли они в среде выполнения или в среде, где находится определение функции, или где-то еще?
Если функция была определена, но еще не вызвана, а формалу присвоено значение по умолчанию, существует ли это значение? Если да, то в какой среде он существует? Если выражение по умолчанию оценивается как константа, присвоено ли формальное значение этому значению, которое будет перезаписано при вызове функции, если задано значение? Если нет, то в какой среде это (фиксированное) значение по умолчанию находится между моментом определения и временем вызова функции?
После того, как функция была вызвана и фактические значения или значения по умолчанию были присвоены формалам, переданы в тело и, если необходимо, определены и / или оценены, продолжают ли формальности существовать? Если да, то в какой среде они существуют?
1 ответ
Формалы для функции существуют как объекты в среде функции, как только экземпляр функции загружается в память при вызове. В Advanced R Хедли Уикхем называет эту среду средой исполнения. Места памяти объектов могут быть доступны через pryr::address()
,
В качестве примера я буду использовать модифицированную версию кода, которую я ранее написал, чтобы проиллюстрировать области памяти в makeVector()
функция из второго задания по программированию для курса Johns Hopkins R Programming на https://www.coursera.org/.
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, что означает, что мы можем получить доступ к объектам в его среде через методы получения и установки, также известные как методы мутатора.
Мы можем загрузить экземпляр 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.
Я предоставляю подробное прохождение объектов в makeVector()
окружение в моем ответе на Кэширование среднего вектора в R.
Что касается вопроса о том, как долго формалы существуют в памяти, они существуют до тех пор, пока среда, созданная для хранения вызываемого экземпляра функции, находится в памяти. Поскольку сборщик мусора работает с объектами, которые не имеют внешних ссылок, если экземпляр функции не сохраняется в объекте, он может быть использован для сборки мусора, как только вызов функции вернет результат в родительскую среду.