В вашем a_counter
есть только одно значение i
.Не два.Когда в функции обнаруживается «свободная переменная», она ищется в среде, в которой была определена функция.Поэтому, когда вы вызываете i
в этой функции, она попадает в глобальную среду, чтобы найти значение.Затем, когда вы делаете <<-
, назначение вообще не происходит в функциональной среде.<<-
всегда начинает искать в родительской среде.Если вы посмотрите на
counter_vars <- function() {
a <- 4
i <<- i + 1
ls()
}
counter_vars()
# [1] "a"
, то увидите, что единственная переменная внутри функции environment / closure - это переменная a
.Переменная i
там не существует.Таким образом, с исходной функцией все i
происходят из глобальной области видимости
a_counter <- function(){
i <<- i + 1 # global i = global i + 1
print(i) # global i still (no local variable has been created)
}
Так что поведение, которое вы видите в not_a_counter
, следует ожидать, потому что <<-
не изменит значения в текущей среде.Это всегда начинает искать одну среду "вверх".Если у вас есть
not_a_counter <- function(){
i <- 0 # local i (always 0)
i <<- i + 1 # global i == local i + 1 (always 0+1)
print(i) # local i (always still 0, local value not changed)
}
Переменная i
больше не «свободна», как только вы определите ее в функции.Таким образом, i <- 0
создает локальную переменную, в части i <<- i + 1
, правая часть i+1
использует эту локальную переменную и присваивает i
в родительской среде.