Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return mutable version of struct in Swift

Tags:

swift

I have a methods that results the struct itself using return self

Unfortunately I am getting the Immutable value of type "Struct name" only has mutable member name 'method name' error.

How can I return such that the struct is mutable?

like image 320
Encore PTL Avatar asked Jun 12 '14 03:06

Encore PTL


People also ask

Is struct immutable in Swift?

Yep, you're right, structs are not immutable. The thing about structs is that they are values. That means every variable is considered a copy, and its members are isolated from changes made to other variables. Structs are not copied on mutation.

Can we modify struct in Swift?

A struct method in Swift being mutating /not- mutating is analogous to a method in C++ being non- const / const . A method marked const in C++ similarly cannot mutate the struct. You can change a var from outside a struct, but you cannot change it from its own methods.

What is mutating function in Swift?

What can a mutating function do? Essentially, a function that's been marked as mutating can change any property within its enclosing value. The word “value” is really key here, since Swift's concept of structured mutations only applies to value types, not to reference types like classes and actors.

How do you copy a struct in Swift?

The best way I have found is to write an initializer method that takes an object of the same type to "copy", and then has optional parameters to set each individual property that you want to change. The optional init parameters allow you to skip any property that you want to remain unchanged from the original struct.


1 Answers

You can mutate structs just fine, but you have to annotate those mutating methods with mutating.

struct SomeStruct {
    var x:Int = 0
    mutating func increment() {
        x++;
    }
}

Edit:

Let me make some clarifications here. Structs can be mutated:

var structA = SomeStruct()
structA.x // 0
structA.increment()
structA.x // 1

But only if you declared it as var. This will not compile:

let structA = SomeStruct()
// structA.increment() // Compile error

Now when you do something like something.methodReturningStruct().mutatingMethod(), the methodReturningStruct() will actually return a copy of the original struct (by virtue of value types). But since you didn't assign it to a var, it will implicitly be treated as a constant (i.e. let) so you get that compiler error.

You can still do the same thing, but you just have to tell swift to use the struct as a var

var structB = something.methodReturningStruct()
structB.mutatingMethod()
like image 122
John Estropia Avatar answered Sep 21 '22 23:09

John Estropia