2
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?

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
Ryan
  • 1,053
  • 12
  • 21
  • 1
    Possible duplicate of [Overlapping accesses to 'urlComponents', but modification requires exclusive access](https://stackoverflow.com/questions/46126574/overlapping-accesses-to-urlcomponents-but-modification-requires-exclusive-acc) – mag_zbc Jul 25 '19 at 15:11

1 Answers1

5

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
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116