2016-12-10 4 views
1

У меня есть код ниже для понимания сложных слоев среды:Функция среды в R

depositor <- function() { 
    balance <- 0 
    function(amount) { 
    balance <<- balance + amount # assign in the parent 
    return(balance) 
    } 
} 
deposit <- depositor() 
deposit(100) 
100 
deposit(32) 
132 

Не могли бы вы объяснить мне, как приведенный выше код работает с точки зрения окружающей среды?

Я не понимаю, от линии deposit <- depositor()

Спасибо, ребята!

+0

'вкладчик' возвращает функцию. Эта функция принимает число в качестве ввода и запоминает и возвращает кумулятивную сумму полученных чисел. –

+0

Это функция внутри функции.Возвращаемый объект 'deposititor()' является функцией, поэтому 'deposit (100)' работает. Моим советом было бы игнорировать источник, где вы его нашли, поскольку это не «правильный» способ поведения. –

+0

Другим интересным экспериментом было бы сделать еще одну функцию «deposit2 <- deposititor()». Эта функция начинается с 0 или 132? –

ответ

4

замочная скважина, чтобы понять этот пример является depositor() Он вернется

depositor() 

function(amount) { 
    balance <<- balance + amount # assign in the parent 
    return(balance) 
    } 
<environment: 0x8936fb0> 

Эта часть несколько прямолинейная. Последний полный блок внутри внешней функции depositor() - это определение анонимной функции function(amount). Таким образом, эта функция становится возвращаемым значением внешней функции, как и любая обычная переменная. Объем как balance, так и этой анонимной функции ограничен внешней функцией, то есть depositor, и ни один из них не может быть напрямую доступен извне.

Однако анонимная функция, возвращенная таким образом, может быть сохранена и повторно использована в родительском фрейме (глобальной среде).

environment(fun = depositor) 
# <environment: R_GlobalEnv> 
environment(fun = deposit) 
# <environment: 0x8a3f5a8> 
parent.env( environment(fun = deposit)) 
# <environment: R_GlobalEnv> 

deposit <- depositor() хранит эту функцию перенастроена в вар имени депозита, и она может быть доступна через него deposit(amountvalue)

Объем amount по-прежнему ограничивается внутренней функции. Невозможно передать значение amount ему через внешнюю функцию, поскольку она не назначена нигде. Это может быть сделано только через прокси-сервер сохраненного deposit(100)


Edit: я снова мой ответ и нашел, что я оставил из наиболее интересной части этого упражнения. Почему значение balance сохраняется от одного вызова другому? то есть, почему следующий вызов не возвращает значение баланса в 0? Каждый новый звонок depositor() (не залог!) вернет функцию со своей родительской/охватывающей средой. Вот доказательство: Он также предложил в выше замечанием @Kota Мори:

deposit<- depositor() 
x<- depositor() 

#following will have two different values 
environment(deposit) 
environment(x) 
# and they will work independently 
x(100); x(20) 
deposit(100);deposit(1000) 

Это суть closure, тема, на которой я мало что могут предложить. Вызов внутренней функции i.e., x() or deposit() не будет вмешиваться в среду, связанную с предыдущим вызовом, так как сама родительская функция не будет вызываться, будет только внутренняя функция. В этом случае внутренняя функция также обновляет баланс в соответствующей среде ограждающей через <<- задания, таким образом, сохраняющиеся значение от одного вызова к следующему


Другое дело, может быть, почему переменная возвращается из функции не приходят с аналогичным корпусом? Это связано с тем, что согласно документации function - the value of the last evaluated expression is returned.