为什么可选链接会导致重叠访问错误?

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

此代码在最后一行导致以下错误。

Overlapping accesses to 'someOptional', but modification requires exclusive access; consider copying to a local variable

如果我将最后一行替换为以下内容,程序将按预期工作。

let foo = someOptional?.foo
someOptional?.bar = foo

为什么第一个示例会导致错误,为什么替代版本(我认为是相同的)不会?

结构是值类型,所以当您执行 let foo = someOptional?.foo 时,someOptional?.foovalue 被复制到局部变量 foo 中。因此,在下一行中,someOptional?.bar = foo 您不再访问 someOptional 来获取 foo 的值,而是直接访问局部变量的值。

这就是为什么 someOptional?.bar = someOptional?.foo 不等同于上述解决方案以及为什么将值保存到局部变量可以解决重叠访问错误的原因。

错误的原因也是您使用的是值类型。在行 someOptional?.bar = someOptional?.foo 中,您正在改变 someOptional 的实例 属性,因此也会改变实例 someOptional,同时访问另一个实例 属性 someOptional.

如果 someOptional 是引用类型,则不会出现该错误,请参见下文:

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