Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot use mutating member on immutable value error when modifying a struct

I have this simple struct.

struct Section {
    let store: Store
    var offers: [Offer]
}

In the VC, I have declared an array of these Sections at the top like so, fileprivate var sections: [Section] = []. And I add some Section objects to in the viewDidLoad().

Later, I need to delete some Offer objects from the offers array inside some Sections.

I iterate through the sections array to find the Section that contains the Offer that needs to be deleted.

for section in sections {
    if let i = section.offers.index(where: { $0.id == offer.id }) {
        section.offers.remove(at: i) // Cannot use mutating member on immutable value: 'section' is a 'let' constant
    }
}

But when I try to delete that particular Offer from the offers array, I get the error Cannot use mutating member on immutable value: 'section' is a 'let' constant.

How do I resolve this?

like image 431
Isuru Avatar asked Jul 31 '17 08:07

Isuru


2 Answers

By default variables defined in the for are let and they cannot be altered. So you have to make it a var. Easier solution:

for var section in sections {
    if let i = section.offers.index(where: { $0.id == offer.id }) {
        section.offers.remove(at: i)
    }
}
like image 132
Whiteshadow Avatar answered Nov 08 '22 03:11

Whiteshadow


When you do the for loop of sections struct (value type) the section variables are immutable. You cannot modify directly their values. You will have to create a mutable version of each Section object, do the modification and assign back to the array (replace the modified object at the right index). For example:

sections = sections.map({
    var section = $0
    if let i = section.offers.index(where: { $0.id == offer.id }) {
        section.offers.remove(at: i)
    }
    return section
})
like image 5
Duyen-Hoa Avatar answered Nov 08 '22 02:11

Duyen-Hoa