Structs & Classes

Swift gives you two ways to bundle data and behavior: structs and classes. They look almost identical to define, but they behave completely differently the moment you assign one to another variable — and getting that distinction is one of the most important things to understand in Swift.

Defining a struct

Swift main.swift
struct Point {
    var x: Int
    var y: Int
}

let p1 = Point(x: 3, y: 4)
print(p1.x, p1.y)
Output
3 4

Swift generates that Point(x:y:) initializer for you automatically — structs get a free "memberwise initializer" without writing one by hand.

Structs are copied on assignment

Swift main.swift
struct Point {
    var x: Int
    var y: Int
}

var a = Point(x: 1, y: 1)
var b = a
b.x = 99

print("a.x = \(a.x), b.x = \(b.x)")
Output
a.x = 1, b.x = 99

var b = a creates a completely independent copy — changing b.x has zero effect on a. Every struct in Swift, including the built-in ones like Array, Dictionary, and String, behaves this way.

Classes are reference types

Swift main.swift
class Account {
    var balance: Int
    init(balance: Int) {
        self.balance = balance
    }
}

let a = Account(balance: 100)
let b = a
b.balance = 500

print("a.balance = \(a.balance)")
Output
a.balance = 500

This time let b = a doesn't copy anything — a and b are two names pointing at the exact same Account instance, so changing balance through b is visible through a too. Notice a and b are both declared with let, yet balance still changed — let on a class reference only stops you from reassigning what a points to, not from mutating the object it points at.

Which one to reach for

Apple's own guidance, and most Swift code in practice, defaults to structs unless you specifically need reference semantics (shared, mutable state that multiple parts of a program need to observe changing together) or need identity that persists independent of a value's contents — both good reasons to reach for a class instead.

Note: this isn't just an academic distinction — it's the single most common source of confusing bugs for people coming from a language where everything is a reference (like Java or Python). Passing a struct into a function hands the function its own copy; passing a class instance hands it a reference to your original object.