Swiftly

Swift 5.7 references for busy coders

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