web-dev-qa-db-de.com

Mutation Member kann nicht für unveränderlichen Wert des Typs verwendet werden

Ich habe folgende Struktur:

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
    }
}

In meiner Klasse möchte ich diese Struktur so verwenden:

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

Ich erhalte folgende Fehlermeldung: Cannot use mutating member on immutable value of type 'ModelOne'. Warum ist das so und wie kann ich das beheben?

14
j0h4nn3s

Wenn Sie Typumwandlung auf Werttypen (solche Strukturen) anwenden, erhalten Sie bei Erfolg einen unveränderlichen copy des angeforderten Werts:

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

Der einzige Weg (wie mir bekannt ist), wie man Werte umwandeln kann, die gegossen werden müssen - Wert neu zuweisen (wie von @Sahil Beri gezeigt, dass Sie eine Variable deklarieren müssen)

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

In Swift 3 konnte ich den Fehler in meinem Fall beheben, indem ich struct in ein class-Objekt änderte.

2
Naishta

Verwenden Sie wie folgt,

struct UserAttributes {
var name:String?
var organizationID:String?
var email:String?

mutating func parseUserAttributes(attribues:[AWSCognitoIdentityProviderAttributeType])->UserAttributes{

    for type in attribues{
        if type.name == "name"{
            name = type.value
        }else if(type.name == "family_name"){
            organizationID = type.value
        }else if(type.name == "custom:role_id"){
            role = type.value
        }else if(type.name == "email"){
            email = type.value
         }

     }

   }  
 }

In einer anderen Datei wie folgt aufrufen,

var userAttributes = UserAttributes()
userAttributes = userAttributes.parseUserAttributes(attribues:attributes)

Das Problem ist, dass Sie data als SuperModel deklariert haben, es jedoch als ModelOne zuordnen. Deklarieren Sie data als ModelOne. Dann geht das Problem weg.

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

Übertragen Sie zuerst die self.data zu ModelOne und rufen Sie dann die setSub-Funktion auf

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

@Shadow von ist richtig. Sie versuchen, eine temporäre Struktur zu mutieren, die unmöglich und meistens unbrauchbar ist, da sie nach der Mutation freigegeben wird. Es ist in der Tat ein ähnliches Problem, wenn versucht wird, die Rückgabestruktur einer Funktion zu ändern. (Siehe Antwort hier: Eigenschaft kann nicht zugewiesen werden: Funktionsaufruf gibt unveränderlichen Wert zurück )

0
Bioche