私は次の構造を持っています:
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'
。なぜそうなのか、どうすれば修正できますか?
値の型(構造体など)に型キャストを適用すると、成功した場合、要求された値の不変copyを受け取ります。
(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
}
}
Swift 3)では、struct
をclass
オブジェクトに変更するだけでエラーを解決できました。
このように使用し、
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)
問題は、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))
}
}
最初にself.dataをModelOneにダウンキャストしてから、setSub関数を呼び出します
if var data = self.data as? ModelOne {
data.setSub(ModelOne.SubModelOne(someVar: 2, othervar: 1))
}
@Shadowが正しい。一時的な構造を変更しようとしますが、これは不可能であり、ほとんどの場合、変更が行われると解放されるため、役に立たなくなります。実際、関数の戻り構造体を変更しようとするのと同様の問題です。 (ここの答えを参照してください: プロパティに割り当てることができません:関数呼び出しは不変の値を返します )