Manuel Manuel - 4 months ago 14
Swift Question

Why are iterators in forEach immutable for a struct but mutable for a class?

The iterator is mutable for a class:

var selections: [Selection] = []

class Selection {
var selected: Bool

init(selected: Bool) {
self.selected = selected
}
}

selections.forEach({ $0.selected = false }) // This works


but not mutable for a struct:

var selections: [Selection] = []

struct Selection {
var selected: Bool
}

selections.forEach({ $0.selected = false }) // This doesn't work because $0 is immutable

Answer

It is not true, that structures are immutable. But you change a different instance of the structure.

Swift obfuscates the way objects and structures are treated.

Objects are reference types, structures are value types. That means, that iterating over objects passes a reference to the object as argument and changing the object that the reference points to, is changing the the original object.

Structures are value types. A new instance of the structure is passed as argument. You change this (just test it inside the block), but this does not effect the original instance of the structure.

In other programming language this different level of indirection is visible, i. e. in Objective-C by an *. In Swift it isn't.