[英]Mutating arrays in a nested Swift struct
I'm new to Swift, so I appreciate any feedback or suggestions on my approach.我是 Swift 的新手,所以我感谢任何关于我的方法的反馈或建议。 For reference, I'm using Xcode 12.1 and Swift 5.3.
作为参考,我使用的是 Xcode 12.1 和 Swift 5.3。 Essentially, I have a series of
struct
s, one of which has an array of strings.本质上,我有一系列
struct
,其中一个有一个字符串数组。 What I'd like to do, is to append a string to that array.我想做的是在该数组中附加一个字符串。 Consider the following code:
考虑以下代码:
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)
I was expecting the final line to print 1
, but instead it prints 0
!我期待最后一行打印
1
,但它打印0
! The compile does not display any errors either.编译也不显示任何错误。 If I change the code so that
struct Thing
is class Thing
and drop the mutating
keyword from its add
method, then the code works.如果我更改代码,使
struct Thing
成为class Thing
并从其add
方法中删除mutating
关键字,则代码可以工作。
Having said that, I don't understand why my original code does not work as I would expect.话虽如此,我不明白为什么我的原始代码不能像我期望的那样工作。 I'm able to append a
Thing
instance to Collection
, but not a string to that same Thing
instance after the fact.我可以将一个
Thing
实例附加到Collection
,但不能在事后将一个字符串附加到同一个Thing
实例。
Have I misunderstood how the mutating
keyword works?我是否误解了
mutating
关键字的工作原理?
You would get your expected 1
if you did:如果您这样做,您将获得预期的
1
:
print(thing!.messages.count)
because you have added the "test"
to thing.messages
, not collection.things.first!.messages
.因为您已将
"test"
添加到thing.messages
,而不是collection.things.first!.messages
。
"Now hold on a second!" “现在等一下!” I hear you say, "I just said
var thing = collection.things.first
on the previous line! How come adding to thing.messages
doesn't imply adding to collection.things.first!.messages
?".我听到你说,“我刚刚在上一行说
var thing = collection.things.first
!为什么添加到thing.messages
并不意味着添加到collection.things.first!.messages
?”。
This is because structs have value semantics.这是因为结构具有值语义。 When you do
var thing = collection.things.first
, you are saying "copy the value of collection.things.first
to a variable called thing
".当您执行
var thing = collection.things.first
,您是在说“将collection.things.first
的值复制到名为thing
的变量”。 You are not saying "the variable thing
now refers to the same thing as collection.things.first
".您不是在说“变量
thing
现在指代与collection.things.first
相同的事物”。 To say that, Thing
has to be a reference type ( class
).也就是说,
Thing
必须是一个引用类型( class
)。
So now you have two copies of the same value, one in thing
and one in collection.things.first
.所以现在你有两个相同值的副本,一个在
thing
,一个在collection.things.first
。 You change the copy stored in thing
.您更改存储在
thing
的副本。 The other copy is unaffected.另一个副本不受影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.