Reputation: 24750
I feel like something is broken with the value semantics here. Consider:
struct A {
var b = 0
mutating func changeB() {
b = 6
}
}
struct B {
var arr = [A]()
func changeArr() {
/* as expected this won't compile
unlss changeArr() is mutating:
arr.append(A())
*/
// but this compiles! despite that changeB is mutating!
for var a in arr {
a.changeB()
}
}
}
Why can this example mutate the struct contents without marking the function as mutating? In true value semantics, any time you change any part of the value, the whole value should be considered changed, and this is usually the behavior in Swift, but in this example it is not. Further, adding a didSet
observer to var arr
reveals that changeArr
is not considered mutation of the value.
Upvotes: 0
Views: 43
Reputation: 51882
The reason changeArr is not mutating is because it isn't really doing anything since it is working on local copies of the A objects. If you really want the method to do something meaningful it needs to be changed to
mutating func changeArrForReal() {
for index in arr.indices {
arr[index].changeB()
}
}
Upvotes: 1
Reputation: 24750
for var a in arr {
a.changeB()
}
This is copying an element from arr
out into a
and leaving arr
unchanged.
If you directly access the elements inside arr
via their indexes, then it will mutate and require the mutating
keyword.
Upvotes: 2