Ответ
Замыкание захватывает экземпляр структуры по значению, так как структуры являются типами-значениями. Это означает создание копии структуры в момент захвата.
Ключевые моменты:
- Для escaping-замыканий копия создается в момент захвата.
- Для изменения (мутирования) структуры внутри замыкания необходимо:
- Объявить экземпляр структуры как
var. - Использовать
mutatingметоды.
- Объявить экземпляр структуры как
Пример:
struct Counter {
var value = 0
mutating func increment() {
value += 1
}
}
var counter = Counter()
// Захват неизменяемой копии
let readClosure = { [counter] in
print(counter.value) // Используется копия, захваченная при создании замыкания
}
// Попытка мутирования требует `var` counter в текущей области видимости
let mutateClosure = {
counter.increment() // Работает, так как counter объявлен как `var`
}
// Для escaping-замыкания мутирование невозможно, так как работает с копией
var escapingClosure: (() -> Void)?
escapingClosure = { [counter] in
// counter здесь — неизменяемая копия. counter.increment() — ошибка компиляции.
}
Почему так? Это поведение гарантирует безопасность работы с типами-значениями в асинхронном контексте, предотвращая неожиданные изменения данных после захвата.