Saran
Saran

Reputation: 6392

How is 'let' implemented?

I pulled this example straight from this Apple page

struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}

and if you assign an instance of this structure to a constant,

let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)

it says we can't change its property values even if it is declared as 'var'

This makes me wonder how let is implemented? I hope any assignments to it can be detected at compile time and show compile error. But in the above case, why does it apply to every property of the structure, regardless of how it is defined?

I tried to search for this, finding it very difficult to search with keyword 'let' as it is quite common term.

Can anyone help me to understand this?

Upvotes: 1

Views: 218

Answers (1)

matt
matt

Reputation: 535222

It's because a struct is a value type. This means it cannot be mutated in place.

Thus, if we have a variable rangeOfFourItems that is a FixedLengthRange struct instance, and we want to set rangeOfFourItems.firstValue, we are actually ripping the struct instance right out of the rangeOfFourItems storage and replacing it with another struct instance with a different firstValue.

To see that this is true, declare rangeOfFourItems with var and attach a setter observer to it, and then change rangeOfFourItems.firstValue:

struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}
var rangeOfFourItems = FixedLengthRange(firstValue:1, length:4) {
    didSet {
        print("Hey, you set me!")
    }
}
rangeOfFourItems.firstValue = 2 // Hey, you set me!

This shows that merely setting the property of this struct instance actually sets the struct variable itself.

But in your code, we cannot do that, because rangeOfFourItems prevents this implicit assignment - it is declared with let, meaning it must remain a constant. Thus, setting rangeOfFourItems.firstValue is prevented at compiler level.

(If FixedLengthRange were a class instead of a struct, it would be a reference type, and would be mutable in place, and setting rangeOfFourItems.firstValue would be legal even if rangeOfFourItems was declared with let.)

Upvotes: 7

Related Questions