I have a code:
class A {
var foo: [Val] = []
var bar: [Val] = []
func a() {
var baz: [Val] {
get {
if foo.isEmpty {
return bar
}
return foo
}
set {
if foo.isEmpty {
bar = newValue
return
}
foo = newValue
}
}
// ....
let lastVal = baz.removeLast()
}
}
I wrote this, but then I was like:
- Wait! But because, I am returning a member of
self
from a getter, this is actually going to create a copy offoo
orbar
- so only the copy will recieve
removeLast()
- so the original array on
self
will not change
But then I tested the code, and found out that actually foo
or bar
gets correctly mutated by removeLast()
!
Question #1:
Why did it happen? Did this happen because the struct after mutation was assigned from scratch through baz
setter to foo
or bar
? Does this mean that there was a copy of struct Array
created as a result of calling mutating func removeLast
?
Question #2:
removeLast
probably modifies the underlying storage of the array, of course. When it was called, did it cause the backing storage of the array to be copied from scratch because there were 2 references to that underlying storage (self
and the copy returned by baz
)? If so, does this mean that this approach is inherently less memory-efficient because of extra copying? Would this not happen if I just called removeLast
on self
member?