Ответ
В Swift нет прямых указателей на память, как в C, но есть безопасные механизмы передачи по ссылке: inout параметры и захват значений по ссылке в замыканиях.
1. Параметр inout
Работает как передача адреса переменной. Функция получает ссылку на исходную переменную и может её модифицировать.
func increment(_ value: inout Int) {
value += 1 // Модификация происходит по ссылке
}
var counter = 0
increment(&counter) // Явная передача с амперсандом `&`
print(counter) // 1
2. Захват по ссылке во вложенной функции (замыкании)
Когда внутренняя функция захватывает переменную из внешней области видимости, она делает это по ссылке, если переменная является ссылочным типом (например, экземпляром класса) или была объявлена с inout.
Ключевой пример: Замыкание, возвращаемое функцией, захватывает локальную переменную counter. Поскольку counter — значение (value type), оно захватывается по ссылке, потому что должно жить дольше, чем область видимости функции makeCounter().
func makeCounter() -> () -> Int {
var count = 0 // Локальная переменная
// Вложенная функция (замыкание) захватывает `count`
func increment() -> Int {
count += 1 // Модифицирует захваченную переменную
return count
}
return increment // Возвращаем замыкание
}
let counterA = makeCounter()
print(counterA()) // 1
print(counterA()) // 2
// `count` продолжает существовать, так как захвачена замыканием по ссылке
let counterB = makeCounter() // Создает новое, независимое захваченное значение
print(counterB()) // 1
Почему это похоже на указатель? Замыкание increment хранит не копию count, а ссылку на область памяти, где хранится её значение. Это позволяет изменять count и сохранять её состояние между вызовами.