Ryan
Ryan

Reputation: 1226

Why does optional chaining cause an overlapping accesses error?

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

Answers (1)

David Pasztor
David Pasztor

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

Related Questions