9.1.3. Manipulating object properties inherently in a struct

What about we try to update a property of an object and write a function directly inside of the struct? So, potentially we will use an inherent function to update a property of the current object.

So, let's try to add a new function inside the struct Car , updateYear() to change the year of a car.

// updating a car's year...
func updateYear(_ year:Int){
    self.year = year
}

So if we put it in the struct, the entire code looks like:

struct Car{
    var make:String
    var model:String
    var year:Int?
    
    init(){
        make = "Not set"
        model = "Not set"
        year = 0
    }
    
    init(make:String, model:String, year:Int) {
        self.make = make
        self.model = model
        self.year = year
    }
    
    init(make:String, model:String){
        self.make = make
        self.model = model
    }
    
    func updateYear(_ year:Int){
        self.year = year
    }
}

If you write the updateYear function, you'll see the following error:

It says that self is immutable. Why?

struct data type is a value type, it is not a reference type. It means, the objects are stored directly in their allocated memory space (RAM), if you access the objects with their variable names, you directly access them from the memory. If you pass a variable to a function through a parameter, it copies the whole object into the function, and never manipulates the original data.

On the other hand, the variables of a reference data type like class do not directly store the objects in their allocated memory space. Rather, the variables will store a pointer (reference) to the objects, and the objects are stored in a separate memory location. So if you pass a reference type variable into a function through parameters, it will pass the reference to the original object. The function can manipulate the original data. It creates a shared mutable state.

(In programming, a mutable object is one whose state or value can be changed after it is created.)

Long story short, since Swift is a safe language, by default the objects of the value data types are not mutating. You have to purposefully make the manipulating functions mutating to allow the functions to mutate the object, or manipulate its original value. So we will change the function above to the following:

mutating keyword defines that this function can update the original data for the object.

So let's use the new method:

It prints:

So, if the object you are using is of a value type, any inherent manipulator needs to be explicitly defined as mutating.

Last updated

Was this helpful?