Swift

方法

本文详细介绍了 Swift 中的方法,包括实例方法、self 属性、在实例方法中修改值类型、类型方法等。

方法是关联了特定类型的函数。类、结构体和枚举都可以定义实例方法(Instance Methods)和类型方法(Type Methods)。

实例方法

实例方法属于特定类、结构体或枚举的实例。它们提供访问和修改实例属性的功能,或提供与实例目的相关的功能。

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)
counter.reset()

self 属性

类型的每个实例都有一个名为 self 的隐式属性,完全等同于该实例本身。主要用于在参数名与属性名冲突时消除歧义。

struct Point {
    var x = 0.0, y = 0.0
    func isToTheRightOf(x: Double) -> Bool {
        return self.x > x
    }
}

在实例方法中修改值类型

结构体和枚举是值类型。默认情况下,值类型的属性不能在其实例方法中被修改。如果需要修改,必须在方法定义前加上 mutating 关键字。

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))")
// 打印 "The point is now at (3.0, 4.0)"

注意:不能在常量结构体类型上调用 mutating 方法。

在 mutating 方法中给 self 赋值

mutating 方法还可以将全新的实例赋值给 self

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

类型方法

类型方法是属于类型本身的方法。在 func 关键字之前使用 static 关键字来指定。类还可以使用 class 关键字来允许子类重写父类的实现。

class SomeClass {
    class func someTypeMethod() {
        // 在这里实现类型方法
    }
}

SomeClass.someTypeMethod()

在类型方法的方法体中,self 指向类型本身,而不是类型的某个实例。这意味着你可以使用 self 来消除类型属性和类型方法参数之间的歧义。

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
        }
    }
}
在 GitHub 上编辑

上次更新于