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?
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
}
}
Dans Swift 3, dans mon cas, j’ai pu résoudre l’erreur en changeant simplement struct
en objet class
.
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))
}
}
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))
}
@ 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 )