web-dev-qa-db-fra.com

Impossible d'utiliser le membre en mutation sur la valeur immuable du type

J'ai struct suivant:

public protocol SuperModel {
    // empty protocol
}
struct ModelOne: SuperModel {
    struct SubModelOne {
        var someVar: Double
        var othervar: Double?
    }
    var sub: SubModelOne?
    mutating func setSub(sub: SubModelOne) {          
        self.sub = sub
    }
}

Dans ma classe, je veux utiliser cette structure comme ça:

final class SomeClass: SuperClass {
    var data: SuperModel
    init() {
        self.data = ModelOne()
    }
    func someFunc() {
        (self.data as! ModelOne).setSub(ModelOne.SubModelOne(someVar: 2, otherVar: 1))
    }
}

J'ai l'erreur suivante: Cannot use mutating member on immutable value of type 'ModelOne'. Pourquoi est-ce vrai et comment puis-je résoudre ce problème?

14
j0h4nn3s

Lorsque vous appliquez le transtypage aux types de valeur (tels que les structures), si vous réussissez, vous recevez immuable copy de la valeur demandée:

(self.data as! ModelOne) // this is copy of data

Le seul moyen (que je sache) de modifier les valeurs à convertir - réaffecter une valeur (comme l'a souligné @Sahil Beri, vous devez déclarer une variable):

func someFunc() {
    if var data = data as? ModelOne {
        data.setSub(ModelOne.SubModelOne(someVar: 2, otherVar: 1))
        self.data = data // you can do this since ModelOne conforms to SuperModel
    }
}
20
Shadow Of

Dans Swift 3, dans mon cas, j’ai pu résoudre l’erreur en changeant simplement struct en objet class.

2
Naishta

Le problème est que vous avez déclaré data en tant que SuperModel mais que vous l'attribuez en tant que ModelOne. Déclarez data comme ModelOne. Alors le problème s'en va.

final class SomeClass: SuperClass {
    var data: ModelOne
    init() {
        self.data = ModelOne()
    }
    func someFunc() {
        (self.data).setSub(ModelOne.SubModelOne(someVar: 2, otherVar: 1))
    }
}
0
iMuzahid

Commencez par décaler self.data vers ModelOne puis appelez la fonction setSub

 if var data = self.data as? ModelOne {
   data.setSub(ModelOne.SubModelOne(someVar: 2, othervar: 1))
 }
0
Sahil

@ Shadow of a raison. Vous essayez de muter une structure temporaire qui est impossible et la plupart du temps inutile car elle sera libérée une fois la mutation effectuée. C'est en fait un problème similaire d'essayer de modifier la structure de retour d'une fonction. (voir la réponse ici: Impossible d'affecter une propriété: l'appel de fonction renvoie une valeur immuable )

0
Bioche