Reputation: 416
I'm struggling with a for-in-loop in Swift. I have two for loops and I expected them be equivalent but the first gives an error and the second works as I expected. Can someone explain me why it's working differently?
protocol Slide {
var title: String { get set }
}
class BasicSlide: NSObject, Slide {
var title: String = "Title"
}
var slides: [Slide]?
slides = [BasicSlide()]
for slide in slides! {
slide.title = "New title" // Cannot assign to property: 'slide' is a 'let' constant
}
for var i in 0 ..< slides!.count {
slides![i].title = "New title"
}
Upvotes: 2
Views: 4183
Reputation: 535765
As you rightly say, slide
is a constant in this expression:
for slide in slides! {
slide.title = "New title" // Cannot assign to property: 'slide' is a 'let' constant
}
If you need to mutate your slide
, simply take a var
reference to it:
for slide in slides! {
var slide = slide
slide.title = "New title" // fine
}
(Do not use the for var
syntax, as it will soon be abolished from the language.)
However, in your example there's a much better way: declare your protocol like this:
protocol Slide : class {
var title: String { get set }
}
Now this code is legal!
for slide in slides! {
slide.title = "New title"
}
Why? Because you've now guaranteed that the adopter of Slide is a class, and a class is a reference type and can be mutated in place. The only reason this failed before is that Swift was afraid the adopter might be a struct.
Upvotes: 6