简体   繁体   English

在嵌套的 Swift 结构中改变数组

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM