Methods

Methods are functions that belong to a particular type. Classes, structures, and enumerations can all define instance methods that work with an instance's data, and type methods that work with the type itself. This is one place Swift differs from C and Objective-C, where only classes can define methods.

Instance methods

An instance method is a function defined inside a type. It has access to all the instance's other methods and properties, and you call it with dot syntax on an instance.

class Counter {
    var count = 0

    func increment() {
        count += 1
    }
    func increment(by amount: Int) {
        count += amount
    }
    func reset() {
        count = 0
    }
}

let counter = Counter()
counter.increment()
counter.increment(by: 5)
print(counter.count)   // → 6

Just like functions, method parameters have argument labels and parameter names, and follow the same rules for default values and so on.

The self property

Every instance has an implicit property called self that refers to the instance itself. You rarely need to write it, because Swift assumes you mean the current instance's property or method. You do need self to disambiguate when a parameter name shadows a property.

struct Point {
    var x = 0.0, y = 0.0

    func isToTheRight(of x: Double) -> Bool {
        return self.x > x   // self.x = property, x = parameter
    }
}

let p = Point(x: 4.0, y: 5.0)
print(p.isToTheRight(of: 1.0))   // → true

Modifying value types from instance methods

Structures and enumerations are value types, and by default their properties can't be changed from within an instance method. To allow it, mark the method mutating. The method can then modify the instance's properties, and the changes are written back to the original value when the method ends.

struct Point {
    var x = 0.0, y = 0.0

    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
print("(\(somePoint.x), \(somePoint.y))")   // → (3.0, 4.0)

Watch out: you can't call a mutating method on a constant of a value type. let fixedPoint = Point(...) followed by fixedPoint.moveBy(...) is a compile-time error, because the value can never change.

Assigning to self within a mutating method

A mutating method can replace the entire instance by assigning a brand-new value to self. For enumerations, this is how a method can switch the instance to a different case.

struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x dx: Double, y dy: Double) {
        self = Point(x: x + dx, y: y + dy)   // replace the whole value
    }
}

enum TriStateSwitch {
    case off, low, high
    mutating func next() {
        switch self {
        case .off:  self = .low
        case .low:  self = .high
        case .high: self = .off
        }
    }
}

var light = TriStateSwitch.low
light.next()
print(light)   // → high

Type methods

Type methods are called on the type itself, not on an instance. Mark them with static. For classes you can instead use class, which allows subclasses to override the method. Inside a type method, self refers to the type, and you can call other type methods without qualification.

struct TemperatureConverter {
    static func celsius(fromFahrenheit f: Double) -> Double {
        (f - 32) * 5 / 9
    }
}

print(TemperatureConverter.celsius(fromFahrenheit: 212))   // → 100.0

class Vehicle {
    class func describe() -> String { "A generic vehicle" }
}
class Car: Vehicle {
    override class func describe() -> String { "A car" }
}

print(Vehicle.describe())   // → A generic vehicle
print(Car.describe())       // → A car

Tip: use static by default for type methods. Reach for class only when you specifically want subclasses to be able to override the behavior.

Recap

Methods give your types behavior. Instance methods operate on a single instance through self; mutating methods let value types change (or even fully replace) themselves; and type methods attach behavior to the type as a whole. Next you'll learn subscripts — a method-like shortcut for accessing elements by index or key.