← Back to list

Mutability in Swift Structs

In Swift, the mutability of a struct is tied directly to the concept of Value Types. Unlike classes (which are reference types), structs…

Tiny · 2026-05-08 06:48 · 0 claps · 2.9 min read
#ios #swift #struct #mutability #ios-app-development
Open on Medium ↗
Wiki topics: 📱 · Mobile Development

Mutability in Swift Structs

Beyond let vs. var: How Structs Actually Mutate in Swift

Beyond let vs. var: How Structs Actually Mutate in Swift

In Swift, the mutability of a struct is tied directly to the concept of Value Types. Unlike classes (which are reference types), structs copy their data when they are passed around.

Because of this, Swift enforces strict rules to ensure that state changes are predictable and safe.

1. The Power of let vs. var in Struct

The mutability of a struct instance depends entirely on the variable it is assigned to.

  • Instance Mutability: Even if a struct has properties defined with var, you cannot change them if the struct instance itself is assigned to a let constant.
struct Person {
    var name: String
}

let p1 = Person(name: "Joe")
p1.name = "Jane" // ❌ Error: Cannot assign to property: 'p1' is a 'let' constant

var p2 = Person(name: "Joe")
p2.name = "Jane" // This compiles now
  • Property Mutability: If a property inside the struct is defined with let, it can never be changed, even if the instance is assigned to a var.
struct Person {
    let name: String
}

var p = Person(name: "Joe")
p.name = "Jane" // ❌ Error: Cannot assign to property: 'name' is a 'let' constant

2. Mutating Methods

By default, Swift assumes that methods on a struct do not modify the properties of that struct. If you want a method to change a property, you must explicitly mark it with the mutating keyword.

How it works under the hood?

When you call a mutating method, Swift doesn't just change a value in memory. Because it’s a value type, the mutating keyword actually allows the method to reassign “self” to a brand-new copy of the struct with the updated values.

struct Point {
    var x = 0.0, y = 0.0

    // This will fail to compile without 'mutating'
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

3. Mutating Computed Properties

Computed properties (getters and setters) also follow mutability rules.

  • The Setter: By default, a set block is always considered mutating because its job is to change the state.
  • The Getter: Normally, a get block is non-mutating (read-only). However, if reading a property needs to update a value, you must mark it as mutating get
struct FileParser {
    var accessCount = 0

    var preview: String {
        mutating get {
            accessCount += 1 // Mutating the state during a 'read'
            return "Accessed \(accessCount) times"
        }
    }
}

The Catch: If you use a mutating get, you can no longer access that property on a let constant, because constants are not allowed to change—even just to "read" a value.

var parser1 = FileParser()
print(parser1.preview) // prints "Accessed 1 times"

let parser2 = FileParser()
print(parser2.preview) // ❌ Error: Cannot use mutating getter on immutable value: 'parser2' is a 'let' constant

4. Testing How a Struct Replaces Itself on mutating

When you modify a struct property, didSet fires for the entire parent object.

Note: In a class, this doesn't happen, because didSet only fires if you point the variable to an entirely different object instance, not when you change a property inside the current one.

// STRUCT BEHAVIOR
struct PointStruct { 
    var x = 0.0 
}

var myPoint = PointStruct() {
    didSet { print("The whole struct was swapped out!") }
}
myPoint.x = 20 // PRINTS: "The whole struct was swapped out!"

// CLASS BEHAVIOR
class PointClass { 
    var x = 0.0 
}

var myClass = PointClass() {
    didSet { print("This will never print.") }
}
myClass.x = 20 // SILENCE: The reference (address) stayed the same.

5. Arrays of Structs: The Collection Effect

Since an Array is also a struct in Swift, if it contains other structs, the rules of mutability apply to the entire chain. If you modify one property of a struct inside an array, the entire array is technically replaced.

struct Task {
    var isDone: Bool
}

var todoList = [Task(isDone: false)] {
    didSet { print("The entire list was updated!") }
}

// Changing one property of one element...
todoList[0].isDone = true 

// PRINTS: "The entire list was updated!"

Take-Aways

  • Variable Type Matters: Mutability is governed by var vs let.
  • Explicit Permission: mutating is a required "permission slip" to change internal state.
  • Predictability: Value Semantics ensure that any change results in a conceptually “new” version, preventing hidden side effects.

Please feel free to leave a comment. Thank you!!!


메타데이터
post_id
35f9f9ff37fd
slug
mutability-in-swift-structs-35f9f9ff37fd
url
https://medium.com/@tinys894/mutability-in-swift-structs-35f9f9ff37fd
canonical_url
https://medium.com/@tinys894/mutability-in-swift-structs-35f9f9ff37fd
author_url
https://medium.com/@tinys894
status
ok
fetched_at
2026-07-10 18:30:51