Захват значений по ссылке
Узнайте, как замыкания захватывают окружающее состояние.
«Захват значений по ссылке» — бесплатный урок Swift Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Что захватывают closures
Closure захватывает переменные и константы из окружающей области видимости, на которые он ссылается. Захваченные переменные хранятся по ссылке, поэтому closure видит последующие изменения.
Захват константы
Closure помнит greeting даже после возврата функции:
func makeGreeter() -> () -> String {
let greeting = "Hello"
return { greeting }
}
let greet = makeGreeter()
print(greet()) // "Hello"Захват переменной по ссылке
Поскольку count является var, closure изменяет одно и то же хранилище при каждом вызове:
func makeCounter() -> () -> Int {
var count = 0
return {
count += 1
return count
}
}
let next = makeCounter()
print(next(), next(), next()) // 1 2 3Общее хранилище
Два closures могут захватить одну переменную и видеть изменения друг друга:
func makePair() -> (() -> Void, () -> Int) {
var value = 0
let inc = { value += 1 }
let read = { value }
return (inc, read)
}
let (inc, read) = makePair()
inc(); inc()
print(read()) // 2Захват отражает последующие изменения
Closure считывает текущее значение переменной в момент вызова, а не её значение при создании closure:
var message = "first"
let show = { print(message) }
message = "second"
show() // "second"Захват по ссылке и по значению
По умолчанию изменяемая переменная захватывается по ссылке. Если нужно зафиксировать копию её значения на момент создания, укажите её в списке захвата, например [x].
Фиксация значения
Список захвата немедленно копирует значение:
var n = 10
let frozen = { [n] in n } // copies 10 now
n = 99
print(frozen()) // 10У каждого closure своё состояние
Каждый вызов фабрики создаёт новую захваченную переменную:
func counter() -> () -> Int {
var c = 0
return { c += 1; return c }
}
let a = counter(), b = counter()
print(a(), a(), b()) // 1 2 1Захват в цикле
Без дополнительных мер closures в цикле могут совместно использовать одну переменную. Используйте список захвата, чтобы сохранить снимок на каждой итерации:
var closures: [() -> Int] = []
for i in 1...3 {
closures.append { [i] in i }
}
print(closures.map { $0() }) // [1, 2, 3]Захват self в методе
Closure, созданный внутри метода, захватывает окружающий экземпляр, позволяя позднее читать и изменять его свойства:
class Bank {
var balance = 0
func deposit() -> () -> Void {
return { self.balance += 10 }
}
}
let bank = Bank()
let add = bank.deposit()
add(); add()
print(bank.balance) // 20Почему это важно
Захват по ссылке лежит в основе счётчиков, аккумуляторов и callback-функций с состоянием — но это также означает, что closure может удерживать объекты в памяти. В следующем разделе мы научимся управлять этим с помощью списков захвата.
func accumulator() -> (Int) -> Int {
var total = 0
return { total += $0; return total }
}
let add = accumulator()
print(add(10), add(5)) // 10 15Быстрая проверка
Как по умолчанию closure захватывает изменяемую переменную?
Итоги
Вы узнали о семантике захвата:
- Closures захватывают переменные из своей области видимости, на которые есть ссылки
- Изменяемые переменные захватываются по ссылке — изменения и мутации являются общими
- Список захвата
[x]фиксирует копию значения при создании - Это позволяет создавать счётчики и callback-функции с состоянием
Далее: escaping closures.
Часто задаваемые вопросы
Урок «Захват значений по ссылке» бесплатный?
Да — полный текст урока «Захват значений по ссылке» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Захват значений по ссылке»?
Узнайте, как замыкания захватывают окружающее состояние. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Захват значений по ссылке»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Захват значений по ссылке
- Убегающие замыкания
- Списки захвата и weak self
- Автозамыкания