Découvrons les méthodes Swift :

Modification des types de valeurs à partir des méthodes d'instances

Les structures et les énumérations sont des types de valeurs. Par défaut, les propriétés d'un type valeur ne peuvent pas être modifiées à partir de ses méthodes d'instances.

Toutefois, si vous devez modifier les propriétés de votre structure ou énumération dans une méthode particulière, vous pouvez activer le comportement de mutation pour cette méthode. La méthode peut alors muter (c'est-à-dire modifier) ses propriétés à partir de la méthode.

Vous pouvez activer ce comportement en plaçant le mot-clé mutating avant le mot-clé func de cette méthode :


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("The point is now at (\(somePoint.x), \(somePoint.y))")
// Prints "The point is now at (3.0, 4.0)"

Les méthodes de mutations peuvent affecter une instance entièrement nouvelle à la propriété implicite self. Résultat identique à la version ci-dessus :


struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        self = Point(x: x + deltaX, y: y + deltaY)
    }
}

Les méthodes de mutations pour les énumérations peuvent définir le paramètre implicite self comme un cas différent de la même énumération :


enum TriStateSwitch {
    case off, low, high
    mutating func next() {
        switch self {
        case .off:
            self = .low
        case .low:
            self = .high
        case .high:
            self = .off
        }
    }
}
var ovenLight = TriStateSwitch.low
ovenLight.next()
// ovenLight is now equal to .high
ovenLight.next()
// ovenLight is now equal to .off

Méthodes de types ou Méthode de classes

Les méthodes d'instances, comme décrites ci-dessus, sont des méthodes que vous appelez sur une instance d'un type particulier. Vous pouvez également définir des méthodes appelées sur le type lui-même. Ces types de méthodes sont appelés méthodes de types ou méthodes de classes.

Vous indiquez les méthodes de types en écrivant le mot-clé static avant le mot-clé func de la méthode. Les classes peuvent utiliser le mot-clé class à la place, pour permettre aux sous-classes de remplacer l'implémentation de cette méthode par la superclasse.


class SomeClass {
    class func someTypeMethod() {
        // type method implementation goes here
    }
}
SomeClass.someTypeMethod()

Par exemple :


struct LevelTracker {
    static var highestUnlockedLevel = 1
    var currentLevel = 1

    static func unlock(_ level: Int) {
        if level > highestUnlockedLevel { highestUnlockedLevel = level }
    }

    static func isUnlocked(_ level: Int) -> Bool {
        return level <= highestUnlockedLevel
    }

    @discardableResult
    mutating func advance(to level: Int) -> Bool {
        if LevelTracker.isUnlocked(level) {
            currentLevel = level
            return true
        } else {
            return false
        }
    }
}

La structure LevelTracker est utilisée avec la classe Player, illustrée ci-dessous, pour suivre et mettre à jour la progression d'un joueur individuel :


class Player {
    var tracker = LevelTracker()
    let playerName: String
    func complete(level: Int) {
        LevelTracker.unlock(level + 1)
        tracker.advance(to: level + 1)
    }
    init(name: String) {
        playerName = name
    }
}