这是我的代码的抽象:
protocol MyProtocol {
var value1: Int {get set}
var value2: Int {get set}
}
struct MyStruct: MyProtocol {
var value1: Int = 1
var value2: Int = 2
var value3: Int = 3
}
struct MyWrapper {
var wrapped: MyProtocol
}
var myWrappedStruct = MyWrapper(wrapped: MyStruct())
我确切地知道我的包装器持有什么,因此我可以将抽象协议类型转换为
MyStruct
。但如果我尝试更改任何值,我会收到编译时错误:
(myWrappedStruct.wrapped as! MyStruct).value3 += 1 // Left side of mutating operator has immutable type 'Int'
当我将
MyStruct
更改为一个类时,它就起作用了。因此,显然,当向下转换结构时,会创建一个不可变的副本以供只读访问。
当实际类型被协议隐藏时,如何改变结构体的属性?
结构是一种值类型。因此,
(myWrappedStruct.wrapped as! MyStruct)
实际上是与包装在myWrappedStruct
内的结构不同的结构。如果你想“变异”它,你必须把它拉出来,变异副本,然后写回:
var myWrappedStruct = MyWrapper(wrapped: MyStruct())
var contents = myWrappedStruct.wrapped as! MyStruct
contents.value3 += 1
myWrappedStruct.wrapped = contents
类是引用类型,因此这些都不适用;您可以就地改变类实例。