Structures and Classes

12.1 Structures (Value Types)

struct Point {
    var x: Double
    var y: Double

    func distance(to other: Point) -> Double {
        ((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y)).squareRoot()
    }

    mutating func move(dx: Double, dy: Double) {   // mutating: modifies self
        x += dx
        y += dy
    }
}

var p1 = Point(x: 0, y: 0)          // free memberwise initializer
var p2 = p1                          // COPY
p2.move(dx: 3, dy: 4)
print(p1.x, p2.x)                    // 0.0 3.0
print(p1.distance(to: p2))           // 5.0

12.2 Classes (Reference Types)

class BankAccount {
    let owner: String
    private(set) var balance: Double

    init(owner: String, balance: Double = 0) {
        self.owner = owner
        self.balance = balance
    }

    func deposit(_ amount: Double) {
        precondition(amount > 0, "Amount must be positive")
        balance += amount
    }

    deinit { print("\(owner)'s account closed") }
}

let acc1 = BankAccount(owner: "Ana")
let acc2 = acc1                      // same instance (reference)
acc2.deposit(100)
print(acc1.balance)                  // 100.0
print(acc1 === acc2)                 // true (identity)

12.3 Struct vs Class

Value (copied) Reference (shared) let instance = fully immutable let reference, mutable properties Stack/inline (generally) Identity (===) Easier (copies) Needs care (or actors)

Apple's guidance: use structs by default. Use classes when you need identity, inheritance, Objective-C interop, or shared mutable state (or consider actors).

12.4 Final Classes and Identity

final class Logger {}                 // can't be subclassed (enables optimizations)
extension Point: Equatable {}         // structs compare by value when Equatable