0Pricing
Swift Academy · Урок

Захват значений по ссылке

Узнайте, как замыкания захватывают окружающее состояние.

«Захват значений по ссылке» — бесплатный урок 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 — локальная установка не требуется.

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

  1. Захват значений по ссылке
  2. Убегающие замыкания
  3. Списки захвата и weak self
  4. Автозамыкания
← Назад к Swift Academy