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?
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
}
}
In Swift 3 konnte ich den Fehler in meinem Fall beheben, indem ich struct
in ein class
-Objekt änderte.
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))
}
}
Ü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))
}
@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 )