我有以下结构:
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'
。为什么会这样,我该如何解决这个问题?
答案 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)