Value types can gain mutating methods through extensions.

Change a value in place

amount
mutating_extensions.swift
Replay: real traced execution (multi-file project)
struct Counter {
    var value: Int
}

extension Counter {
    mutating func add(_ amount: Int) {
        value += amount
    }
}

let amount = 4
var counter = Counter(value: 10)
counter.add(amount)
let message = "counter=\(counter.value)"

print(message)
struct Counter {
    var value: Int
}

extension Counter {
    mutating func add(_ amount: Int) {
        value += amount
    }
}

let amount = 1
var counter = Counter(value: 10)
counter.add(amount)
let message = "counter=\(counter.value)"

print(message)
struct Counter {
    var value: Int
}

extension Counter {
    mutating func add(_ amount: Int) {
        value += amount
    }
}

let amount = 7
var counter = Counter(value: 10)
counter.add(amount)
let message = "counter=\(counter.value)"

print(message)
  1. amount ← 4, counter ← Counter(value: 10)

    11let amount→ 4 = 4  //@amount=1, 712var counter→ Counter(value: 10) = Counter(value: 10)13counterCounter(value: 10).add(amount4)14let message = "counter=\(counter.value)"
  2. value ← 14

    5extension Counter {6    mutating func add(_ amount4: Int) {7        value→ 14 += amount48    }
  3. counter ← Counter(value: 14), message ← counter=14

    12var counter = Counter(value: 10)13counter→ Counter(value: 14).add(amount4)14let message→ counter=14 = "counter=\(counter.value14)"1516print(messagecounter=14)
    outputcounter=14
  1. amount ← 1, counter ← Counter(value: 10)

    11let amount→ 1 = 112var counter→ Counter(value: 10) = Counter(value: 10)13counterCounter(value: 10).add(amount1)14let message = "counter=\(counter.value)"
  2. value ← 11

    5extension Counter {6    mutating func add(_ amount1: Int) {7        value→ 11 += amount18    }
  3. counter ← Counter(value: 11), message ← counter=11

    12var counter = Counter(value: 10)13counter→ Counter(value: 11).add(amount1)14let message→ counter=11 = "counter=\(counter.value11)"1516print(messagecounter=11)
    outputcounter=11
  1. amount ← 7, counter ← Counter(value: 10)

    11let amount→ 7 = 712var counter→ Counter(value: 10) = Counter(value: 10)13counterCounter(value: 10).add(amount7)14let message = "counter=\(counter.value)"
  2. value ← 17

    5extension Counter {6    mutating func add(_ amount7: Int) {7        value→ 17 += amount78    }
  3. counter ← Counter(value: 17), message ← counter=17

    12var counter = Counter(value: 10)13counter→ Counter(value: 17).add(amount7)14let message→ counter=17 = "counter=\(counter.value17)"1516print(messagecounter=17)
    outputcounter=17
mutating extension A mutating extension method can update `self` for value types such as structs.