不能在类型的不可变值上使用变异成员

时间:2016-08-04 09:50:05

标签: swift struct

我有以下结构:

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

在我的课堂上,我想使用这样的结构:

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

我收到以下错误:Cannot use mutating member on immutable value of type 'ModelOne'。为什么会这样,我该如何解决这个问题?

6 个答案:

答案 0 :(得分:25)

将类型转换应用于值类型(例如结构)时,如果成功,则会收到所请求值的不可变副本

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

唯一的方法(我知道)如何改变需要转换的值 - 重新分配值(因为@Sahil Beri指出你需要声明变量):

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

答案 1 :(得分:3)

在Swift 3中,就我而言,我只需将struct更改为class对象即可解决错误。

答案 2 :(得分:0)

问题是您已将data声明为SuperModel,但将其分配为ModelOne。将data声明为ModelOne。然后问题就消失了。

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

答案 3 :(得分:0)

首先将self.data向下转换为ModelOne,然后调用setSub函数

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

答案 4 :(得分:0)

@Shadow是对的。你试图改变一个不可能的临时结构,大部分时间都是无用的,因为它会在突变完成后被释放。事实上,尝试修改函数的返回结构也是一个类似的问题。 (见答案:Cannot assign to property: function call returns immutable value

答案 5 :(得分:0)

像这样使用

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
         }

     }

   }  
 }

在这样的其他文件调用中,

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