Ответ
Да, 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-типов он управляет копированием значения.
Ответ 18+ 🔞
Ну, слушай, смотри, как это работает, а то многие думают, что capture list — это только для классов, чтобы weak/unowned делать. А вот нихуя!
Для этих твоих структур, перечислений и прочей value-хуйни capture list работает по-другому, но логика там железная. Суть в чём: когда ты value-тип в квадратные скобочки засовываешь, замыкание хватает моментальную копию значения. Ту самую, которая была в секунду создания замыкания. И всё, приехали. Дальше хоть исходную переменную в пизду разнеси — замыканию похуй, у него своя, отдельная, законсервированная копия.
Смотри, как это выглядит, чтоб не быть мудаком, который потом три часа дебажит:
var number = 10
// Вот тут, в этот самый момент, замыкание схватило значение 10 и засунуло себе в карман.
let closure = { [number] in
print("Захваченное значение: (number)") // И будет тут вечно сидеть эта десятка, как ядрёна вошь!
}
number = 20 // А тут мы исходную переменную переписали. Волнение ебать!
closure() // А вызов-то что покажет? Правильно, старую добрую десятку. "Захваченное значение: 10"
А нахуя это вообще надо, спросишь? Да затем же, нахуй!
- Зафиксировать состояние, блядь. Чтобы твоё замыкание не бегало за изменяющейся переменной, как собака за хвостом, а работало с тем, что было актуально, когда его создали. Как фотография, ёпта.
- Отрезать неявные зависимости. Особенно кайфово, когда у тебя
varкакая-нибудь летучая. Захватил копию — и спи спокойно, никто тебе снаружи логику не сломает. - Для reference-типов capture list — это про управление памятью (
weak,unowned). Для value-типов — это про управление данными, про то, какую именно копию значения ты хочешь использовать. Вот и вся разница, чих-пых тебя в сраку.