Methods and Subscripts

14.1 Instance and Type Methods

struct Counter {
    private(set) var count = 0
    mutating func increment(by amount: Int = 1) { count += amount }
    mutating func reset() { self = Counter() }         // assign a new self in mutating methods
    static func makeStartingAt(_ value: Int) -> Counter {
        var c = Counter()
        c.count = value
        return c
    }
}

14.2 Subscripts

struct Matrix {
    let rows: Int, columns: Int
    private var grid: [Double]

    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        grid = Array(repeating: 0, count: rows * columns)
    }

    subscript(row: Int, column: Int) -> Double {
        get {
            precondition(indexIsValid(row, column), "Index out of range")
            return grid[row * columns + column]
        }
        set { grid[row * columns + column] = newValue }
    }

    private func indexIsValid(_ r: Int, _ c: Int) -> Bool { (0..<rows).contains(r) && (0..<columns).contains(c) }
}

var m = Matrix(rows: 2, columns: 2)
m[0, 1] = 1.5

extension Array {
    subscript(safe index: Int) -> Element? { indices.contains(index) ? self[index] : nil }
}
[1, 2, 3][safe: 10]    // nil

enum Planet: Int { case mercury = 1, venus
    static subscript(n: Int) -> Planet? { Planet(rawValue: n) }   // static subscript
}