SLN
SLN

Reputation: 5082

Mutable and Modifialbe what is the meaning of them?

Let's start with some code segments

struct DigitS {
    var number = 42
    init(_ n: Int) {
        self.number = n
    }
    mutating func replace() {
        self = DigitS(12) // mutating 
    }
}

class DigitC {
    var number = 42
    init(_ n: Int) {
        self.number = n
    }
    func replace() {
        self = DigitC(12) //#Cannot assign to value: "self" is immutable
    }
}

For a very long time, I was very confused about the meaning of mutable, modifiable. Here are some of my understandings so far, would be nice if you can point out all errors it may have

  1. Mutating function in the structure type above does not "mutates" the instance, it will replace the old value of the variable by a totally new one

  2. Mutating means: the action like assignment, initialization or mutating function does not modifies the current value but a triggers a replacement

  3. A class typed variable's value is immutable, but you can modify/change the current value (this is the reason the compiler gives out the warning, please see the comments with #)

  4. The setter observer, can only be called if the type is a value type, because setter tells if the variable has been mutated/replaced (please see code below)

    struct Digit {
        var number = 12
    }   
    var b = Digit() {
        didSet{ print("number is set") }
    }  
    b.number = 22 // observer is called
    
    
    
    class Digit {
         var number = 12
        }   
    var b = Digit() {
         didSet{ print("number is set") }
        }
    
    b.number = 22 // observer is not called
    

Thanks for your time and help

Upvotes: 0

Views: 2517

Answers (2)

SLN
SLN

Reputation: 5082

The observer observes the value change, the value of a class typed variable is the reference points to the object. To trigger the property observer, the reference has to be changed.

    class Digit {
        var number = 12
    }

    var a = Digit()

    var b = Digit() {
        didSet{ print("number is set") }
    }

    b.number = 22 // observer is called

    b = a //observer is called here!!

Upvotes: 0

GetSwifty
GetSwifty

Reputation: 7746

Dealing with memory tend be better explained using images, but I'll give it a go here:

  1. You're sort of right, it's actually changing the data stored at the location of the variable.

Given a simple struct with a mutator:

struct Example {
    var text: String

    mutating func changeText(to newText: String) {
        self.text = newText
    }
}

let constantExample = Example(text: "Test") //Makes a section of memory that isn't allowed to change.
constantExample.changeText(to: "Other Test") //This doesn't work because constantExample isn't mutable.

var mutableExample = Example(text: "Test") //Makes a section of memory that is allowed to change.
mutableExample.changeText(to: "Other Test") //This doesn't make a new copy, but rather changes the value in mutableExample's section of memory

If you were to use the specific case you mentioned:

mutating func changeText(to newText: String) {
    self = Example(text: "A new text")
}

mutableExample will still reside in the same memory location, but you are manually Creating a completely new instance of the Example and then copying that data from that instance to mutableExample.

  1. The opposite :) Mutating changes the instance in-place. You can change that instance by copying a different value, (as happens in the self = example), but the instance is still the same instance, just with a different value.

  2. When creating a class variable, you are creating a reference to a section of memory. When setting or changing that reference var variableName = classInstance the location of reference remains the same once initialized, but the location being referenced (if a var) can then change.

  3. You're functionally correct, but missing some nuance. In the struct example, as previously stated the actual value of the instance is changing. In the class example, the referenced memory is changing, but the actual value stored within b does not change.

Upvotes: 2

Related Questions