0

I'm new to Swift, so I appreciate any feedback or suggestions on my approach. For reference, I'm using Xcode 12.1 and Swift 5.3. Essentially, I have a series of structs, one of which has an array of strings. 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! 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.

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.

Have I misunderstood how the mutating keyword works?

1
  • collection.things[0].add("test") Commented Oct 30, 2020 at 13:14

1 Answer 1

2

You would get your expected 1 if you did:

print(thing!.messages.count)

because you have added the "test" to thing.messages, not 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?".

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". You are not saying "the variable thing now refers to the same thing as collection.things.first". To say that, Thing has to be a reference type (class).

So now you have two copies of the same value, one in thing and one in collection.things.first. You change the copy stored in thing. The other copy is unaffected.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.