R Academy · Урок

Глобальная и локальная область видимости

Различайте .GlobalEnv, окружения функций и замыкания.

Урок 3 из 413 шагов

«Глобальная и локальная область видимости» — бесплатный урок R Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.

Локальные переменные в функциях

Переменные, которым внутри тела функции присваивается значение с помощью <- или =, являются локальными для этой функции. Они создаются в собственном окружении функции и исчезают после её возврата. Они никогда не изменяют область видимости вызывающего кода.

x <- 'global'
f <- function() {
  x <- 'local'   # creates a new local binding, does not modify global x
  cat('Inside f: x =', x, '\n')
}
f()
cat('Outside f: x =', x, '\n')  # still 'global'

Параметры функций являются локальными

Параметры функций также являются локальными переменными. Изменение параметра внутри функции не влияет на аргумент в окружении вызывающего кода. R передаёт аргументы по значению (с копированием при изменении).

double_it <- function(n) {
  n <- n * 2      # modifies local copy only
  cat('Inside:', n, '\n')
}
my_n <- 5
double_it(my_n)
cat('Outside:', my_n, '\n')  # still 5

<<- для присваивания в глобальной области

<<- (суперприсваивание) ищет совпадение по цепочке родительских окружений и присваивает значение первой найденной привязке. Если совпадений нигде нет, привязка создаётся в глобальном окружении. Используйте этот оператор умеренно: чрезмерное применение <<- усложняет понимание функций.

total <- 0
add_to_total <- function(x) {
  total <<- total + x
}
add_to_total(10)
add_to_total(25)
add_to_total(5)
cat('Total:', total, '\n')

<<- выполняет поиск вверх по цепочке

<<- не присваивает значение безусловно в глобальном окружении — оператор поднимается по цепочке родительских окружений и присваивает значение первому окружению, где это имя уже существует. Если переменная существует во внешней функции, она будет изменена именно там.

outer <- function() {
  n <- 0
  increment <- function() n <<- n + 1
  increment()
  increment()
  cat('n in outer:', n, '\n')  # n was in outer's env, updated there
}
outer()
# n does NOT appear in global env
cat('n in global:', exists('n', envir = globalenv()), '\n')

assign() для явного выбора окружения

assign('name', value, envir = e) напрямую присваивает значение определённому окружению. Это более явный вариант по сравнению с <<-; он полезен, когда у Вас есть объект-окружение и нужно точно записать в него значение.

my_env <- new.env(parent = emptyenv())
assign('score', 95, envir = my_env)
assign('name', 'Alice', envir = my_env)
cat('score:', get('score', envir = my_env), '\n')
cat('name :', get('name',  envir = my_env), '\n')

local() — изолированные блоки кода

local({...}) вычисляет выражение в новом локальном окружении. Переменные, созданные внутри блока, не попадают в глобальное окружение. Это удобно для временных вычислений, которые не должны засорять рабочую область.

result <- local({
  temp1 <- 100
  temp2 <- 200
  temp1 + temp2   # the last expression is returned
})
cat('result:', result, '\n')
cat('temp1 in global:', exists('temp1'), '\n')  # FALSE

local() и функция для изоляции

И local(), и немедленно вызываемая функция обеспечивают изоляцию области видимости. local() короче и удобнее для разовой изоляции, а именованная функция лучше, если нужно повторно использовать или тестировать логику.

# Option A: local()
result_a <- local({
  x <- 7
  y <- 3
  x * y
})
# Option B: immediately invoked function
result_b <- (function() {
  x <- 7
  y <- 3
  x * y
})()
cat(result_a, result_b, '\n')
cat('x in global:', exists('x'), '\n')

Чтение глобальных переменных из функции

Функции могут читать переменные из своего объемлющего окружения (глобального или любого другого) без специального синтаксиса. Это стандартное лексическое разрешение имён. Однако сильная зависимость от глобального состояния усложняет тестирование функций — по возможности предпочитайте явные аргументы.

tax_rate <- 0.20   # global configuration
apply_tax <- function(price) {
  price * (1 + tax_rate)  # reads tax_rate from global
}
cat(apply_tax(100), '\n')
cat(apply_tax(250), '\n')

Затенение переменных

Если локальная переменная имеет то же имя, что и глобальная, локальная привязка затеняет глобальную. Внутри функции используется локальная версия. Глобальная переменная не изменяется. Если это сделано непреднамеренно, могут возникнуть трудно обнаружимые ошибки.

mean <- 99   # shadows base R's mean() function
cat(mean, '\n')   # prints 99, not the function
# To call the real mean, use base:: prefix
cat(base::mean(c(1, 2, 3, 4, 5)), '\n')
rm(mean)   # remove the shadow

Окружения function()

При каждом вызове функции R создаёт новое окружение для этого вызова, делая родительским окружение, объемлющее функцию. Локальные переменные разных вызовов не влияют друг на друга, в том числе при рекурсивных вызовах.

factorial_r <- function(n) {
  # Each recursive call has its own local n
  if (n <= 1) return(1)
  n * factorial_r(n - 1)
}
cat('5! =', factorial_r(5), '\n')
cat('7! =', factorial_r(7), '\n')

rm() для удаления переменных

rm('name') или rm(name) удаляет привязку из текущего (или указанного) окружения. Используйте эту функцию для очистки временных переменных. Передайте envir = e, чтобы удалить привязку из определённого окружения.

x <- 42
y <- 'hello'
cat('Before rm:', ls(), '\n')
rm(x)
cat('After rm(x):', exists('x'), '\n')
rm('y')
cat('After rm(y):', exists('y'), '\n')

Быстрая проверка

Что делает <<-, чего не делает обычный оператор <-?

Область видимости: основные выводы

Основные выводы о глобальной и локальной областях видимости:

  • <- внутри функции создаёт локальную переменную — глобальная переменная не изменяется
  • Параметры функций являются локальными; R передаёт аргументы по значению (с копированием при изменении)
  • <<- поднимается по цепочке родительских окружений и изменяет первую подходящую привязку
  • assign('x', val, envir=e) позволяет явно указать окружение для присваивания
  • local({...}) создаёт временную область видимости без создания именованной функции
  • Избегайте затенения важных имён, таких как mean, c, T
# Demonstrate local + <<- cleanly
running_sum <- 0
local({
  values <- c(10, 20, 30, 40)
  for (v in values) running_sum <<- running_sum + v
})
cat('Running sum:', running_sum, '\n')
cat('values in global:', exists('values'), '\n')
Можно начать бесплатно

Изучай R с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
43
Уроки
159

Часто задаваемые вопросы

Урок «Глобальная и локальная область видимости» бесплатный?

Да — полный текст урока «Глобальная и локальная область видимости» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.

Чему я научусь в уроке «Глобальная и локальная область видимости»?

Различайте .GlobalEnv, окружения функций и замыкания. Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать R Academy?

Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Глобальная и локальная область видимости»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке R Academy?

Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Что такое окружение в R?
  2. Правила лексической области видимости
  3. Глобальная и локальная область видимости
  4. Создание и проверка окружений
← Назад к R Academy