Skip to content
AgileLogics
5 min read

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
  • mutating tells Swift, and the reader, that the method changes the instance. You can only call it on a var.
  • isAbove only reads, so it isn't mutating and works on let instances too.
  • private(set) means the property can be read from anywhere but only changed inside the struct — so the only way to change count is 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 adding mutating.
  • Calling a mutating method on a let instance: cannot use mutating member on immutable value.