What is the difference between a class and a struct and when would you use them?
The core difference
struct is a value type — assigning or passing it creates an independent copy. class is a reference type — assigning or passing it shares the same underlying instance.
struct Point { var x, y: Int }
var p1 = Point(x: 0, y: 0)
var p2 = p1
p2.x = 5
// p1.x is still 0
class Counter { var value = 0 }
let c1 = Counter()
let c2 = c1
c2.value = 5
// c1.value is now also 5
The concrete mechanical differences
struct | class | |
|---|---|---|
| Semantics | Value — copied on assignment | Reference — shared on assignment |
| Memory | Stack (or inline), or COW-backed heap | Always heap-allocated |
| Mutability control | let makes whole thing immutable | Reference can be let while properties still mutate |
| ARC / reference counting | None on the struct itself | Always ARC-managed |
| Inheritance | No inheritance (protocols only) | Supports subclassing, overriding |
| Identity | No identity | Has identity — === |
| Thread safety implications | Copies are inherently safer to share | Shared mutable state needs explicit synchronization |
| Dispatch | Static dispatch | Vtable dispatch for non-final methods |
When to use each
Default to struct unless you have a specific reason to need a class.
Use a class when you need:
- Identity
- Shared mutable state
- Inheritance
- Objective-C interop
- Reference semantics for lifecycle-bound objects (network session, file handle)
Use a struct when:
- Representing data/values
- You want copy-on-write safety by default
- Performance matters and it fits on the stack
- Concurrency safety matters
A concrete rule of thumb
Ask: “if I have two of these with identical values, should they be considered the same thing, or two different things that happen to look alike?” Same thing → struct. Two different things → class.
The SwiftUI-specific nuance
SwiftUI’s View types are structs (cheap to recreate on every body evaluation), while its state-holding types (@Observable classes, ObservableObject) are classes specifically because they need reference/shared-identity semantics.
One-liner if pressed: “Structs are value types — copied on assignment, no identity, no ARC overhead on their own — while classes are reference types — shared on assignment, have identity, and are ARC-managed. Default to structs for anything representing data/values, and reach for classes specifically when you need shared mutable state, object identity, inheritance, or Objective-C interop.”