Methods and mutating
Prerequisites: Properties
Methods on structs can read properties freely. But because structs are
values, a method that changes a property must be marked
mutating.
Example
struct Counter {
private(set) var count = 0
mutating func increment(by amount: Int = 1) {
count += amount
}
mutating func reset() {
count = 0
}
func isAbove(_ limit: Int) -> Bool {
count > limit
}
}
var clicks = Counter()
clicks.increment()
clicks.increment(by: 5)
print(clicks.count)
print(clicks.isAbove(3))
clicks.reset()
print(clicks.count)
Expected output
6
true
0
mutatingtells Swift, and the reader, that the method changes the instance. You can only call it on avar.isAboveonly reads, so it isn'tmutatingand works onletinstances too.private(set)means the property can be read from anywhere but only changed inside the struct — so the only way to changecountis through its methods. (Access control has its own lesson.)
self
Inside a method, self refers to the current instance. You rarely need
to write it, except to tell a property apart from a parameter with the
same name:
struct Player {
var name: String
mutating func rename(name: String) {
self.name = name
}
}
Static methods
static func defines a method on the type itself — often used for
alternative ways to create an instance:
struct Point {
var x: Double
var y: Double
static func origin() -> Point {
Point(x: 0, y: 0)
}
}
print(Point.origin())
Point(x: 0.0, y: 0.0)
Common mistakes
- Forgetting
mutating:cannot assign to property: 'self' is immutable— the compiler's fix-it suggests addingmutating. - Calling a
mutatingmethod on aletinstance:cannot use mutating member on immutable value.