How to Use Computed Properties in Swift
What you’ll build or solve
You’ll define computed properties that derive values from stored properties.
When this approach works best
Computed properties work best when:
Learn Swift on Mimo
- A value can always be derived from other stored properties, like area from width and height.
- You want to avoid duplicated state that can drift out of sync, like storing both side and area.
- You want a clean property-style API instead of calling a method, like
user.initialsinstead ofuser.getInitials().
This is a bad idea when the computation is heavy and runs often. In that case, cache the result or compute it once and store it.
Prerequisites
- Xcode or a Swift Playground
- Basic knowledge of Swift structs or classes and stored properties
Step-by-step instructions
Step 1: Create a read-only computed property
A read-only computed property has only a getter. Swift calculates it every time you access it.
structRectangle {
varwidth:Double
varheight:Double
vararea:Double {
width*height
}
}
What to look for
- No initial value for
area, because Swift does not store it. - Changing
widthorheightchangesareaautomatically.
Step 2: Create a read-write computed property with a setter
Add a setter when you want assignments to update other stored properties.
importFoundation
structSquare {
varside:Double
vararea:Double {
get {side*side }
set {side=sqrt(newValue) }
}
}
What to look for
newValueis available automatically insideset.- The setter updates a stored property (
side), notareaitself.
Step 3: Know what to look for with computed properties
Computed properties stay predictable when you follow a few rules.
What to look for
- Single-expression getters can omit
return, which keeps simple computed properties short. - Setters should update stored properties, not the computed property itself.
- Custom setter parameter names exist, but renaming
newValuerarely improves clarity unless the meaning is specific.
set(newArea) {
side=sqrt(newArea)
}
- Computed properties run on every access, so avoid heavy work in getters if the property is read often.
Examples you can copy
Example 1: Derived full name
structUser {
varfirstName:String
varlastName:String
varfullName:String {
"\(firstName) \(lastName)"
}
}
letuser=User(firstName:"Jordan",lastName:"Lee")
print(user.fullName)
Example 2: Temperature conversion with two-way updates
importFoundation
structTemperature {
varcelsius:Double
varfahrenheit:Double {
get {celsius*9/5+32 }
set {celsius= (newValue-32)*5/9 }
}
}
vartemp=Temperature(celsius:0)
print(temp.fahrenheit)
temp.fahrenheit=212
print(temp.celsius)
Example 3: Cart total that never goes stale
structCartItem {
varprice:Double
varquantity:Int
}
structCart {
varitems: [CartItem]
vartotal:Double {
items.reduce(0) {$0+ ($1.price*Double($1.quantity)) }
}
}
letcart=Cart(items: [
CartItem(price:10,quantity:2),
CartItem(price:5,quantity:3)
])
print(cart.total)
Common mistakes and how to fix them
Mistake 1: Storing derived data that can drift out of sync
What you might do:
structRectangle {
varwidth:Double
varheight:Double
vararea:Double
}
Why it breaks: area can become wrong when width or height changes.
Correct approach:
structRectangle {
varwidth:Double
varheight:Double
vararea:Double {
width*height
}
}
Mistake 2: Creating infinite recursion in a setter
What you might do:
importFoundation
structSquare {
varside:Double
vararea:Double {
get {side*side }
set {area=newValue }
}
}
Why it breaks: Assigning to area inside its own setter calls the setter again.
Correct approach:
importFoundation
structSquare {
varside:Double
vararea:Double {
get {side*side }
set {side=sqrt(newValue) }
}
}
Troubleshooting
- If you see
Cannot assign to property: 'x' is a get-only property, add asetblock. - If you see
Cannot use mutating member on immutable value, change your instance fromlettovarbefore setting a computed property. - If values seem wrong after setting, confirm the setter updates the right stored property.
- If performance feels slow, move heavy work out of the getter or cache the result.
Quick recap
- Use a read-only computed property to derive values without storing them.
- Add a setter when assignments should update stored properties.
- Use
newValueinside setters to read the incoming value. - Update stored properties in setters, not the computed property itself.
- Avoid heavy computations in getters when the property is accessed often.
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