How to Use Struct vs Class in Swift
What you’ll build or solve
You’ll learn how structs and classes differ and how that impacts copying, mutation, and shared state.
When this approach works best
Understanding struct vs class works best when:
Learn Swift on Mimo
- You design data models for an app.
- You notice unexpected copying or shared mutations.
- You build SwiftUI views or UIKit controllers.
- You structure business logic and services.
This comparison is less useful for very small scripts where object design is not important.
Prerequisites
- Xcode installed
- Basic Swift syntax
- Familiarity with variables and functions
Step-by-step instructions
Step 1: Understand value vs reference behavior
Structs are value types. Classes are reference types.
Struct example
structUser {
varname:String
}
varuser1=User(name:"Alex")
varuser2=user1
user2.name="Sam"
print(user1.name)// Alex
print(user2.name)// Sam
user2 is a copy. Changing it does not affect user1.
Class example
classUser {
varname:String
init(name:String) {
self.name=name
}
}
varuser1=User(name:"Alex")
varuser2=user1
user2.name="Sam"
print(user1.name)// Sam
print(user2.name)// Sam
Both variables point to the same instance.
What to look for
- Structs create independent copies.
- Classes share the same instance.
- Shared mutation only happens with classes.
This difference is the most important deciding factor.
Step 2: Choose struct for simple data models
Use a struct when:
- You store plain data.
- You want safer, predictable copying.
- You work with SwiftUI state.
- You do not need inheritance.
Example:
structProduct {
vartitle:String
varprice:Double
}
Structs are ideal for lightweight models. They reduce accidental shared state and make code easier to reason about.
Step 3: Choose class for shared or complex behavior
Use a class when:
- Multiple parts of your app must share the same instance.
- You need inheritance.
- You manage lifecycle or identity.
- You work with UIKit view controllers.
Example:
classSessionManager {
varisLoggedIn=false
}
If two objects reference the same SessionManager, changes affect both.
Classes are useful for services and controllers.
Step 4: Understand inheritance differences
Structs do not support inheritance. Classes do.
classAnimal {
funcspeak() {
print("Animal sound")
}
}
classDog:Animal {
overridefuncspeak() {
print("Bark")
}
}
You cannot subclass a struct.
If your design requires polymorphism or shared base behavior, use a class.
Step 5: Consider mutability and intent
Struct methods that modify properties require mutating.
structCounter {
varvalue:Int
mutatingfuncincrement() {
value+=1
}
}
Classes do not require mutating.
This encourages immutability with structs, which reduces side effects.
If your type represents a value, like a coordinate or settings object, a struct usually fits better.
Examples you can copy
Example 1: Settings as a struct
structSettings {
varisDarkMode:Bool
varfontSize:Int
}
varsettings=Settings(isDarkMode:true,fontSize:16)
settings.fontSize=18
Each copy of Settings is independent.
Example 2: Shared manager as a class
classAppState {
varisLoggedIn=false
}
letstate1=AppState()
letstate2=state1
state2.isLoggedIn=true
print(state1.isLoggedIn)// true
Both references point to the same object.
Example 3: Comparing memory behavior
Struct:
structPoint {
varx:Int
vary:Int
}
varp1=Point(x:0,y:0)
varp2=p1
p2.x=10
print(p1.x)// 0
Class:
classPointClass {
varx:Int
vary:Int
init(x:Int,y:Int) {
self.x=x
self.y=y
}
}
varp1=PointClass(x:0,y:0)
varp2=p1
p2.x=10
print(p1.x)// 10
The behavior changes entirely.
Common mistakes and how to fix them
Mistake 1: Expecting struct to share updates
What you might do:
varuser1=User(name:"Alex")
varuser2=user1
user2.name="Sam"
Why it surprises you:
Structs are copied, so changes do not propagate.
Correct approach:
Use a class if you need shared state.
Mistake 2: Using class when value semantics are safer
What you might do:
Kotlin
classCoordinate {
varx:Int
vary:Int
}
Why it causes issues:
Shared references can lead to unintended side effects.
Correct approach:
Kotlin
structCoordinate {
varx:Int
vary:Int
}
Use structs for simple values.
Troubleshooting
If changes to one variable affect another unexpectedly, check whether you used a class.
If you need inheritance but used a struct, switch to a class.
If copying large models feels expensive, remember Swift optimizes structs efficiently.
If you struggle with shared mutable state, prefer structs.
Quick recap
- Structs are value types. Classes are reference types.
- Struct copies are independent.
- Class instances are shared.
- Use struct for simple data models.
- Use class for shared state or inheritance.
- Choose based on behavior, not habit.
Join 35M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot