Jarvis
Jarvis

Reputation: 63

How to use mutating member on immutable value?

I got the solution but can't understand why it works.

my struct is QuizBrain()

whenever i try to use this code, i got an error:

Cannot use mutating member on immutable value: function call returns immutable value

btw the checkAnswer method is mutated.

code:

let userGotItRight = QuizBrain().checkAnswer(pressedAnswer)

The solution is creating an object from that struct and using it. Can someone explain why it is necessary to create an object?

code:

var quizBrain = QuizBrain()

let userGotItRight = quizBrain.checkAnswer(pressedAnswer)

Upvotes: 3

Views: 532

Answers (1)

Mr.SwiftOak
Mr.SwiftOak

Reputation: 1834

It is actually mix of let vs var and class vs struct. Here are some examples. Firstly lets declare your code as both struct and class:

struct QuizBrainStruct {
    var answer: String?
    mutating func checkAnswer(_ str: String) {
        self.answer = str
    }
}

class QuizBrainClass {
    var answer: String?
    func checkAnswer(_ str: String) {
        self.answer = str
    }
}

let pressedAnswer = "pressed"

In this example we I will use QuizBrainStruct() and QuizBrainClass() which are similar but not the same. Your QuizBrain() is defined as struct, therefore if you make this statement:

let userGotItRight = QuizBrainStruct().checkAnswer(pressedAnswer)// would fail with: Cannot use mutating member on immutable value is a 'let' constant

It is basicelly treated the same way as declaring let variable and then calling the function on in as following:

let s = QuizBrainStruct()
s.checkAnswer(pressedAnswer) // would fail with: Cannot use mutating member on immutable value: 's' is a 'let' constant

Your workoroud works if you declare it as a var, because values of var can be mutated:

var s2 = QuizBrainStruct()
s2.checkAnswer(pressedAnswer)

However there is more into the topic and that is that Struct is passed as value, therefore "s" cannot be mutated. If you declare it as a class (which is passed as reference) . You can do the following with no errors:

let userGotItRight = QuizBrainClass().checkAnswer(pressedAnswer)

Here is the difference why:

let s1 = QuizBrainStruct()
let s2 = s1 // s1 value is a new value and it is copy of s1

let c1 = QuizBrainClass()
let c2 = c1 // c1 value is reference to c1 (same value)

For more info about struct vs class you can read following swift doc . You can read more about value and reference type here: value vs reference passing

Upvotes: 2

Related Questions