Можно ли захватывать value-типы (структуры, перечисления) в capture list замыкания в Swift?

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

Ответ

Да, capture list в Swift работает с value-типами (структуры, перечисления, кортежи) так же, как и с reference-типами (классы).

Ключевое поведение: При захвате value-типа в списке захвата создается неизменяемая копия значения на момент создания замыкания.

Пример:

var number = 10

// Захватываем текущее значение `number` (10)
let closure = { [number] in
    print("Захваченное значение: (number)") // Всегда выведет 10
}

number = 20 // Изменение исходной переменной
closure() // Вывод: "Захваченное значение: 10"

Зачем это нужно?

  • Фиксация состояния: Чтобы замыкание работало со значением, актуальным на момент его определения, а не на момент вызова.
  • Предотвращение неявных зависимостей: Особенно полезно при захвате изменяемых (var) value-типов, чтобы избежать неожиданного поведения, если исходная переменная изменится позже.
  • Для reference-типов capture list используется для управления подсчетом ссылок (создания weak или unowned ссылок). Для value-типов он управляет копированием значения.