我是Swift的新手,因此,感谢您对我的方法提出的任何反馈或建议。作为参考,我正在使用Xcode 12.1和Swift 5.3。本质上,我有一系列struct
,其中一个具有字符串数组。我想做的是将一个字符串附加到该数组。考虑以下代码:
struct Collection {
var things: [Thing] = []
mutating func add(_ thing: Thing) {
things.append(thing)
}
}
struct Thing {
var messages: [String] = []
mutating func add(_ message: String) {
messages.append(message)
}
}
var collection = Collection()
collection.add(Thing())
var thing = collection.things.first
thing!.add("test")
print(collection.things.first!.messages.count)
我期望最后一行打印1
,但是它却打印0
!编译也不显示任何错误。如果我更改代码以使struct Thing
为class Thing
,并从其mutating
方法中删除add
关键字,则代码可以正常工作。
话虽如此,我不明白为什么我的原始代码无法按预期工作。我可以在Thing
后面附加一个Collection
实例,但是在事实之后不能在同一Thing
实例上附加一个字符串。
我是否误解了mutating
关键字的工作原理?
答案 0 :(得分:2)
如果您这样做,将会得到预期的1
:
print(thing!.messages.count)
因为您已将"test"
添加到thing.messages
,而不是collection.things.first!.messages
。
“现在等一下!”我听到你说:“我在前一行刚刚说过var thing = collection.things.first
!添加到thing.messages
并不意味着添加到collection.things.first!.messages
吗?”。
这是因为结构具有值语义。当您执行var thing = collection.things.first
时,您是在说“将collection.things.first
的值复制到名为thing
的变量中”。您不是说“变量thing
现在引用与collection.things.first
相同。”也就是说,Thing
必须是引用类型(class
)。
因此,现在您有两个具有相同值的副本,一个在thing
中,一个在collection.things.first
中。您更改了存储在thing
中的副本。另一个副本不受影响。