Reputation: 1226
struct SomeStruct {
var foo: String?
var bar: String?
}
var someOptional: SomeStruct? = SomeStruct()
someOptional?.bar = someOptional?.foo
This code causes the following error on the last line.
Overlapping accesses to 'someOptional', but modification requires exclusive access; consider copying to a local variable
If I replace the last line with the following, then the program works as expected.
let foo = someOptional?.foo
someOptional?.bar = foo
Why is the first example causing an error, and why does the alternate version (which I would assume to be identical) not?
Upvotes: 2
Views: 160
Reputation: 54706
Structs are value types, so when you do let foo = someOptional?.foo
, the value of someOptional?.foo
is copied into the local variable foo
. Hence in your next line, someOptional?.bar = foo
you don't access someOptional
to get the value of foo
anymore, but you access the value of the local variable directly.
This is why someOptional?.bar = someOptional?.foo
is not equivalent to the above solution and why saving the value to a local variable resolves the overlapping accesses error.
The cause of the error is also the fact that you are using value types. In the line someOptional?.bar = someOptional?.foo
you are mutating an instance property of someOptional
and hence mutating the instance someOptional
as well, while at the exact same time accessing another instance property of someOptional
.
If someOptional
was a reference type, you wouldn't get that error, see below:
class SomeClass {
var foo: NSString? // `NSString` is a reference type
var bar: NSString?
}
let someOptionalClass: SomeClass? = SomeClass()
someOptionalClass?.bar = someOptionalClass?.foo
let fooRef = someOptionalClass?.foo
someOptionalClass?.bar = fooRef
Upvotes: 5