A struct method marked mutating can change the instance's stored properties.

Change a value type

step
mutating_methods.swift
Replay: real traced execution (multi-file project)
struct Counter {
    var value: Int

    mutating func advance(by amount: Int) {
        value = value + amount
    }
}

let step = 2
var counter = Counter(value: 10)
counter.advance(by: step)
counter.advance(by: step)

print("step=\(step)")
print("value=\(counter.value)")
struct Counter {
    var value: Int

    mutating func advance(by amount: Int) {
        value = value + amount
    }
}

let step = 1
var counter = Counter(value: 10)
counter.advance(by: step)
counter.advance(by: step)

print("step=\(step)")
print("value=\(counter.value)")
struct Counter {
    var value: Int

    mutating func advance(by amount: Int) {
        value = value + amount
    }
}

let step = 4
var counter = Counter(value: 10)
counter.advance(by: step)
counter.advance(by: step)

print("step=\(step)")
print("value=\(counter.value)")
  1. step ← 2, counter ← Counter(value: 10)

    9let step→ 2 = 2  //@step=1, 410var counter→ Counter(value: 10) = Counter(value: 10)11counterCounter(value: 10).advance(by: step2)12counter.advance(by: step)
  2. value ← 12

    pass 1 of 2
    4mutating func advance(by amount2: Int) {5    value→ 12 = value + amount26}
  3. counter ← Counter(value: 12)

    10var counter = Counter(value: 10)11counter→ Counter(value: 12).advance(by: step2)12counterCounter(value: 12).advance(by: step2)
  4. value ← 14

    pass 2 of 2
    4mutating func advance(by amount2: Int) {5    value→ 14 = value + amount26}
  5. counter ← Counter(value: 14)

    11counter.advance(by: step)12counter→ Counter(value: 14).advance(by: step2)1314print("step=\(step2)")15print("value=\(counter.value14)")
    outputstep=2
    value=14
  1. step ← 1, counter ← Counter(value: 10)

    9let step→ 1 = 110var counter→ Counter(value: 10) = Counter(value: 10)11counterCounter(value: 10).advance(by: step1)12counter.advance(by: step)
  2. value ← 11

    pass 1 of 2
    4mutating func advance(by amount1: Int) {5    value→ 11 = value + amount16}
  3. counter ← Counter(value: 11)

    10var counter = Counter(value: 10)11counter→ Counter(value: 11).advance(by: step1)12counterCounter(value: 11).advance(by: step1)
  4. value ← 12

    pass 2 of 2
    4mutating func advance(by amount1: Int) {5    value→ 12 = value + amount16}
  5. counter ← Counter(value: 12)

    11counter.advance(by: step)12counter→ Counter(value: 12).advance(by: step1)1314print("step=\(step1)")15print("value=\(counter.value12)")
    outputstep=1
    value=12
  1. step ← 4, counter ← Counter(value: 10)

    9let step→ 4 = 410var counter→ Counter(value: 10) = Counter(value: 10)11counterCounter(value: 10).advance(by: step4)12counter.advance(by: step)
  2. value ← 14

    pass 1 of 2
    4mutating func advance(by amount4: Int) {5    value→ 14 = value + amount46}
  3. counter ← Counter(value: 14)

    10var counter = Counter(value: 10)11counter→ Counter(value: 14).advance(by: step4)12counterCounter(value: 14).advance(by: step4)
  4. value ← 18

    pass 2 of 2
    4mutating func advance(by amount4: Int) {5    value→ 18 = value + amount46}
  5. counter ← Counter(value: 18)

    11counter.advance(by: step)12counter→ Counter(value: 18).advance(by: step4)1314print("step=\(step4)")15print("value=\(counter.value18)")
    outputstep=4
    value=18

Follow the Mutations

  1. step starts as 2.
  2. counter starts with value = 10.
  3. The first advance(by: step) adds 2, making 12.
  4. The second call adds 2 again, making 14.
  5. The program prints step=2 and value=14. | action | counter value | | --- | --- | | start | 10 | | first advance by 2 | 12 | | second advance by 2 | 14 |
mutating Struct instances are values. A `mutating` method is explicit about changing the stored properties of that value.

Exercise: mutating_methods.swift

Reproduce step=2 and value=14, then use the pinned step variants 1 and 4 to predict value=12 and value=18.