SLN SLN - 6 months ago 9
Swift Question

Why I can change/reassigned a constant value that Instantiated from a class

I've created the following class

class Person {
var firstName: String
var lastName: String

init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}


func fullName() -> String {
return "\(firstName) \(lastName)"
}
}


Then I instantiated a constant value from the class

let john = Person(firstName: "Johnny", lastName: "Applessed")


Question: Why I can change the content of the variable
john
? Isn't it a constant? Can someone explain that for me, thanks a lot.

john.firstName = "John"

print(john.firstName) // -> John

Answer

As @Wain has said – it's due to the nature of reference types. The instance being a let constant only means you cannot assign a new reference to it – but says nothing about the actual mutability of the instance itself.

If you change your class to a struct, you'll see how the behaviour differs with value types, as changing a property changes the actual value of your Person – therefore you are unable to do so if it's a let constant. However I somewhat doubt you'll want to make your Person a struct, as two people with the same name shouldn't be considered to be the same person.

If you only wish your properties to be assigned upon initialisation (and then read-only for the lifetime of the instance), then I would recommend making them let constants (instead of making their setters private). This will ensure that you cannot even change their value from within your class, once assigned.

The rule is as long you give a property a value before the super.init() call – you can make it a let constant (in this case, you just have to assign them in the initialiser before using self).

class Person {
    let firstName: String
    let lastName: String

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }

...
Comments