Mutating function not mutating

Hi, I'm pretty new to Swift and am a little confused on how the 'mutating' keyword functions.

I have this struct:

struct Road: Identifiable, Equatable, Hashable, Encodable, Decodable {
    
    let id: UUID
    
    // Customization
    var roadname: String
    var encodedImage: Data?
    
    // Functionality
    var wordlist: [WordPair]
    var milestones: [Milestone]
    var milestonesCompleted: Int {
        var count = 0
        for item in milestones {
            if item.completed {
                count += 1
            }
        }
        return count
    }
}

// Initialisers
extension Road {
    init(id: UUID = UUID() ) {
        self.id = id
        self.roadname = "New Road"
        self.wordlist = []
        self.milestones = []
    }
    
    init(id: UUID = UUID(), wordlist: [WordPair], roadname: String, imagedata: UIImage? ) {
        self.id = id
        self.roadname = roadname
        self.encodedImage = imagedata?.pngData()
        self.wordlist = wordlist
        
        self.milestones = Road.createMilestones(words: wordlist)
    }
}

extension Road {
    func getImage() -> UIImage? {
        if let createImage = encodedImage{
            return UIImage(data: createImage)
        } else {
            return nil
        }
    }
    
    mutating func updateImage(image: Data){
        self.encodedImage = image
    }
    
    mutating func cloneRoad(road: Road) {
        self.roadname = road.roadname
        self.encodedImage = road.encodedImage
        self.wordlist = road.wordlist
    }
    
    mutating func getNewMilestones() {
        self.milestones = Road.createMilestones(words: wordlist)
    }
    
    static func createMilestones( words: [WordPair ]) -> [Milestone] {
        let MAX_PER_MILESTONE = 10;
        
        var temporaryWordList: [WordPair] = []
        var tmpmilestones: [Milestone] = []
        
        for item in words {
            temporaryWordList.append(item)
            if (temporaryWordList.count % MAX_PER_MILESTONE == 0 &&
                temporaryWordList.count != 0 ){
                tmpmilestones.append(Milestone(id: (temporaryWordList.count / MAX_PER_MILESTONE), wordList: temporaryWordList))
            }
        }
        tmpmilestones.append(Milestone(id: ( tmpmilestones.count + 1 ), wordList: temporaryWordList))
        
        return tmpmilestones
    }
}

I want to update 'milestones' down the line, an array of objects (also structs) computed from the updated wordlist.

My issue is that the wordlist is updated, but calling the function

mutating func getNewMilestones() {
        self.milestones = Road.createMilestones(words: wordlist)
    }

Doesn't change anything in the actual object. The changes exist when checking values within the function, but the actual change is lost outside.

Whats going on here?

Thank you very much in advance!

Could you show complete code so that we can try reproduce issue ?

My guess is that you're thinking of the Road struct as a reference type (object) not a value type (um … value).

An instance of a reference type is represented by a single value, and variables set to that value all refer to the same underlying instance. (You can have different instances with different values, but that's not what I'm talking about here.)

A value type is represented by an unlimited number of "copies" (identical "instances", if you like) of the value, and if you mutate a copy, you don't mutate the original instance of the value.

For example, if you call a function and pass in a Road value as a parameter, that function works on a copy of the value, not the original value. If you mutate the value inside the function, the calling function's code won't see a change — the value you changed was discarded when the called function returned.

If you have an array of Road values, then not only is each element a value type, but the array itself is a value type. If you're not expecting this, it's easy to make the mistake of modifying copies of the elements (which won't cause the array to change), or modifying a copy of the array itself (which won't cause the original array to change either).

Mutating function not mutating
 
 
Q