Являются ли замыкания (closures) в Swift ссылочным (reference) или значимым (value) типом?

«Являются ли замыкания (closures) в Swift ссылочным (reference) или значимым (value) типом?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Замыкания в Swift являются ссылочными типами (reference types). Они размещаются в куче (heap), и при присваивании замыкания новой переменной или передаче в функцию копируется ссылка на один и тот же экземпляр замыкания, а не его содержимое.

Почему это важно:

  • Изменения состояния переменных, захваченных замыканием (captured variables), видны всем владельцам ссылки на это замыкание.
  • Это поведение отличается от структур (value types), которые копируются.

Пример, демонстрирующий reference semantics:

var counter = 0
let incrementer = { counter += 1 } // Замыкание захватывает `counter` по сильной ссылке

let anotherReference = incrementer // Копируется ссылка, а не новое замыкание

incrementer() // counter = 1
anotherReference() // counter = 2
print(counter) // Выведет: 2

Управление захватом: Чтобы избежать непреднамеренного совместного использования состояния, используйте списки захвата (capture lists). Например, [counter] захватит копию значения на момент создания замыкания.