Alexander Sviridov
Alexander Sviridov

Reputation: 111

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

I want to use mutating functions for objects declared in extension. And really want to make its chaining with functions. I have no idea how to fix this.

protocol SomeProtocol {
    var value: Int { get set }
}

extension SomeProtocol {
    mutating func mutatingMethod(_ newValue: Int) -> Self {
        value = newValue
        return self
    }
}

class SomeClass: SomeProtocol {
    var value: Int = 0
    
    func otherMethod() {
        
    }
}

// Error: 
// Cannot use mutating member on immutable value: 
// function call returns immutable value
var someObj = SomeClass().mutatingMethod(3)

someObj.otherMethod()

Upvotes: 0

Views: 670

Answers (1)

lazarevzubov
lazarevzubov

Reputation: 2315

If you want to keep SomeProtocol available to be adopted by structs and/or don't want to change your declarations, the error can be avoided just by the way you make calls. For example, this works:

var someObj = SomeClass()
someObj = someObj.mutatingMethod(3)
someObj.otherMethod()

The reason is that mutating members can only be called on var declarations. Though, in your call chain the result of SomeClass() is not assigned anywhere and Swift compiler treats it as if it was let.

For example, it won't work also if you call it like this:

let someObj = SomeClass() // The only difference is let.
someObj = someObj.mutatingMethod(3)
someObj.otherMethod()

The error is the same, but worded more obviously: cannot use mutating member on immutable value: 'someObj' is a 'let' constant.

Upvotes: 3

Related Questions