Guide
Structs vs classes in Swift
A struct is copied when you hand it over; a class is shared. Start with a struct, and reach for a class when one thing really has to be seen and changed by everybody.
The one difference that matters
Structs and classes look almost the same: both have properties and methods. The difference is what happens when you assign one, pass it to a function, or put it in an array.
struct Hero {
var name: String
var health: Int
}
var hero = Hero(name: "Ash", health: 30)
var shadow = hero // a second, independent Hero
shadow.health = 8
print(hero.health) // 30
print(shadow.health) // 8
The second line made a copy. Changing one cannot reach the other. This is called value
semantics, and most of the types in Swift's own library — Int, String,
Array, Dictionary — work this way.
Now the same thing with a class:
class Party {
var gold: Int
init(gold: Int) { self.gold = gold }
}
let ours = Party(gold: 100)
let theirs = ours // a second name for the same party
theirs.gold = 40
print(ours.gold) // 40
print(ours === theirs) // true: one object, two names
Assigning a class copies the reference, not the object. There is one party, and both names see every change.
What follows from that
letmeans different things. Aletstruct cannot change at all; aletclass reference cannot point elsewhere, but the object it points to can still change — which is whytheirs.gold = 40above was allowed.- A struct method that changes the struct says so. It is marked
mutating, or Swift refuses it:struct Hero { var name: String var health: Int mutating func takeHit(_ damage: Int) { health -= damage } } - Classes have identity and inheritance; structs have neither.
===asks whether two names are the same object, a class can inherit from another, and it can run code indeinitwhen it goes away. - Classes can form reference cycles. Two objects that hold each other strongly are never
freed;
weakandunownedare how you break the loop. A struct is copied, so it cannot hold on to itself this way.
Which one to choose
Choose a struct by default. A value nobody else can change behind your back is easier to reason about, and Apple's own guidance says the same.
Choose a class when the thing you are modelling is genuinely one thing that several parts of the program must see — a game session everyone at the table watches, a connection, a shared cache — or when a framework asks you to subclass one of its classes.
The test is a question about your design, not about speed: if two parts of the program hold this, should a change made by one be seen by the other? Yes means a class. No means a struct.
Where SwiftQuest teaches it
Structs and copies are The Value Kingdom (island 4): you predict whether one character or two changed, then build and amend values without touching the original. Classes are Reference Citadel (island 6), where a party shares one table, and The Memory Dungeon (island 10) is where reference cycles are found and broken.
Learn it by writing it
SwiftQuest is a Swift course in fifteen islands. Every quest has you write real Swift and run it on a real compiler, in your browser, with nothing to install. It opens soon, and the first two islands are free.