Нельзя использовать мутирующий элемент по неизменяемому значению типа
У меня есть следующая структура:
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'
. Почему это так и как я могу это исправить?
Ответы
Ответ 1
Когда вы применяете тип casting к типам значений (такие структуры), если они успешны, вы получаете неизменяемую копию запрашиваемого значения:
(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
}
}
Ответ 2
В Swift 3, в моем случае, я смог разрешить ошибку, просто изменив struct
на объект class
.
Ответ 3
Проблема в том, что вы объявили 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))
}
}
Ответ 4
Сначала сбрасываем self.data в ModelOne, затем вызываем функцию setSub
if var data = self.data as? ModelOne {
data.setSub(ModelOne.SubModelOne(someVar: 2, othervar: 1))
}
Ответ 5
@Правая. Вы пытаетесь изменить временную структуру, которая невозможна и большую часть времени бесполезна, поскольку она будет выпущена после того, как будет выполнена мутация. На самом деле это аналогичная проблема с попыткой изменить структуру возврата функции. (см. ответ здесь: Нельзя назначить свойство: вызов функции возвращает неизменяемое значение)
Ответ 6
Используйте как это,
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)