Variables
Variables and constants are used to hold pieces of data. Variables can change over time (mutable), while constants must stay the same (immutable). The word “variables” is usually used to describe both variables and constants. Variables that belong to a struct, class, or enum are properties.
Variables
Variables are declared with var
:
var greeting = "Hello"
var numberOfToys = 8
var isMorning = true
Variable declarations can include type annotations for clarity:
var greeting: String = "Hello"
var numberOfToys: Int = 8
var isMorning: Bool = true
Variables are mutable. Their values can change:
var numberOfToys: Int = 8
numberOfToys += 1
print(numberOfToys) // Prints "9"
Constants
Constants are declared with let
:
let greeting = "Hello"
let numberOfToys = 8
let isMorning = true
Constant declarations can include type annotations for clarity:
let greeting: String = "Hello"
let numberOfToys: Int = 8
let isMorning: Bool = true
Constants are not mutable. Their values cannot change:
let numberOfToys: Int = 8
numberOfToys += 1 // ❌ Error: numberOfToys is not mutable
Computed variables (get
and set
)
Computed variables are like normal variables, but instead of actually storing a value, they provide a getter and (optional) setter that returns a value and set other properties indirectly.
In the example below, age
is computed from birthday
when it’s requested. Because there is no setter, the keyword get
can be omitted:
import Foundation
let df = DateFormatter()
df.dateFormat = "d MMMM yyyy"
var birthday = df.date(from: "5 June 1999")!
var age: Int {
Calendar.current
.dateComponents([.year],
from: birthday,
to: Date()).year!
}
print(age) // 20
birthday = df.date(from: "5 June 2002")!
print(age) // 17
In the example below, distanceInFeet
has both a getter and a setter. Because there is a setter, the keyword get
is required for the getter:
var distanceInMeters: Float = 100
var distanceInFeet: Float {
get {
distanceInMeters * 3.28
}
set(newDistanceInFeet) {
distanceInMeters = newDistanceInFeet / 3.28
}
}
print(distanceInMeters) // 100.0
print(distanceInFeet) // 328.0
distanceInFeet = 250
print(distanceInMeters) // 76.21951
print(distanceInFeet) // 250.0
distanceInMeters = 800
print(distanceInMeters) // 800.0
print(distanceInFeet) // 2624.0
willSet
willSet
can be used to execute some code before a variable’s value is set:
var distance = 5 {
willSet {
print("distance will be set")
}
}
distance = 10
Output:
distance will be set
The new value can be accessed in willSet
:
var distance = 5 {
willSet(newDistance) {
print("distance will be set to \(newDistance)")
}
}
distance = 10
Output:
distance will be set to 10
didSet
didSet
can be used to execute some code after a variable’s value is set. The old value can still be accessed in this code block with oldValue
:
var distance = 5 {
didSet {
print("distance was set to \(distance)")
print("its old value was: \(oldValue)")
}
}
distance = 10
Output:
distance was set to 10
its old value was: 5
willSet
with didSet
willSet
with didSet
can be used together:
var distance = 5 {
willSet(newDistance) {
print("distance will be set to \(newDistance)")
}
didSet {
print("distance was set to \(distance)")
print("its old value was: \(oldValue)")
}
}
distance = 10
Output:
distance will be set to 10
distance was set to 10
its old value was: 5