How capture lists work and how their behaviour differ for value and reference types in Swift

Code in Swift
2 min readMar 9, 2022

As part of my job search I did an automated test at Toggle which made me realise I forgot a lot of fundamental reasons for why things work the way they work in Swift. I knew correct answers to most of the questions, but I wasn’t always 100% certain why they were correct. So I decided to dig in and research all of them.

The questions themselves are pretty generic so I won’t try and change them from what they were in the test, I hope the Toggle folks forgive me. Here’s the first one.

So the question is what the print output is going to be. Intuitively it feels the answer is “Sum is 8”. And it is indeed correct. But why?

Processor is a value type. So when the caputre list creates a Processor constant it copies the values from the variable that we declared before the closure. And from then on, these two instances of Processor exist completely separately from each other. When we change the .b value of the first instance to 20, the .b value of the second one is not changed.

If Processor was a class and not a struct, the capture list would still create a new instance of it but it would point to the same object as the first one. And if you changed the .b value in one of them, it would be changed everywhere. So if it was a class, the answer would be “Sum is 23”.

But what if we remove the capture list entirely? Would anything change?

Now we don’t create a second instance of Processor and work with the first one directly. So in both cases the .b value is changed to 20 before the sum is calculated. Therefore, for both value and reference types the answer is “Sum is 23”.

If you liked this article please share it on Twitter or any other social network. It helps more than you think!

--

--