Swift5.1—类型方法

简介: Swift5.1—类型方法

实例方法是被某个类型的实例调用的方法。你也可以定义在类型本身上调用的方法,这种方法就叫做类型方法。在方法的 func 关键字之前加上关键字 static,来指定类型方法。类还可以用关键字 class 来指定,从而允许子类重写父类该方法的实现。


注意

在 Objective-C 中,你只能为 Objective-C 的类类型(classes)定义类型方法(type-level methods)。在 Swift 中,你可以为所有的类、结构体和枚举定义类型方法。每一个类型方法都被它所支持的类型显式包含。


类型方法和实例方法一样用点语法调用。但是,你是在类型上调用这个方法,而不是在实例上调用。下面是如何在 SomeClass 类上调用类型方法的例子:


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



在类型方法的方法体(body)中,self 属性指向这个类型本身,而不是类型的某个实例。这意味着你可以用 self 来消除类型属性和类型方法参数之间的歧义(类似于我们在前面处理实例属性和实例方法参数时做的那样)。


一般来说,在类型方法的方法体中,任何未限定的方法和属性名称,可以被本类中其他的类型方法和类型属性引用。一个类型方法可以直接通过类型方法的名称调用本类中的其它类型方法,而无需在方法名称前面加上类型名称。类似地,在结构体和枚举中,也能够直接通过类型属性的名称访问本类中的类型属性,而不需要前面加上类型名称。


下面的例子定义了一个名为 LevelTracker 结构体。它监测玩家的游戏发展情况(游戏的不同层次或阶段)。这是一个单人游戏,但也可以存储多个玩家在同一设备上的游戏信息。


游戏初始时,所有的游戏等级(除了等级 1)都被锁定。每次有玩家完成一个等级,这个等级就对这个设备上的所有玩家解锁。LevelTracker 结构体用类型属性和方法监测游戏的哪个等级已经被解锁。它还监测每个玩家的当前等级。


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
        }
    }
}


LevelTracker 监测玩家已解锁的最高等级。这个值被存储在类型属性 highestUnlockedLevel 中。


LevelTracker 还定义了两个类型方法与 highestUnlockedLevel 配合工作。第一个类型方法是 unlock(_:),一旦新等级被解锁,它会更新 highestUnlockedLevel 的值。第二个类型方法是 isUnlocked(_:),如果某个给定的等级已经被解锁,它将返回 true。(注意,尽管我们没有使用类似 LevelTracker.highestUnlockedLevel 的写法,这个类型方法还是能够访问类型属性 highestUnlockedLevel

除了类型属性和类型方法,LevelTracker 还监测每个玩家的进度。它用实例属性 currentLevel 来监测每个玩家当前的等级。


为了便于管理 currentLevel 属性,LevelTracker 定义了实例方法 advance(to:)。这个方法会在更新 currentLevel 之前检查所请求的新等级是否已经解锁。advance(to:) 方法返回布尔值以指示是否能够设置 currentLevel。因为允许在调用 advance(to:) 时候忽略返回值,不会产生编译警告,所以函数被标注为 @discardableResult 属性


下面,Player 类使用 LevelTracker 来监测和更新每个玩家的发展进度:


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
    }
}


Player 类创建一个新的 LevelTracker 实例来监测这个用户的进度。它提供了 complete(level:) 方法,一旦玩家完成某个指定等级就调用它。这个方法为所有玩家解锁下一等级,并且将当前玩家的进度更新为下一等级。(我们忽略了 advance(to:) 返回的布尔值,因为之前调用 LevelTracker.unlock(_:) 时就知道了这个等级已经被解锁了)。


你还可以为一个新的玩家创建一个 Player 的实例,然后看这个玩家完成等级一时发生了什么:


var player = Player(name: "Argyrios")
player.complete(level: 1)
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// 打印“highest unlocked level is now 2”


如果你创建了第二个玩家,并尝试让他开始一个没有被任何玩家解锁的等级,那么试图设置玩家当前等级将会失败:


player = Player(name: "Beto")
if player.tracker.advance(to: 6) {
    print("player is now on level 6")
} else {
    print("level 6 has not yet been unlocked")
}
// 打印“level 6 has not yet been unlocked”


注:使用static或者class修饰类型属性或者类型方法,两者区别是static不能被子类重写而class可以被子类重写。

目录
相关文章
|
6月前
|
存储 Swift iOS开发
在Swift编程语言中,集合类型`Set`
在Swift编程语言中,集合类型`Set`
55 2
|
8天前
|
Swift 索引 容器
Swift 泛型-扩展泛型类型
Swift 泛型-扩展泛型类型
16 2
|
8天前
|
Swift 索引
Swift 泛型-类型约束
Swift 泛型-类型约束
19 1
|
12天前
|
Swift iOS开发
Swift 方法
10月更文挑战第29天
16 4
|
17天前
|
安全 Swift iOS开发
Swift 可选(Optionals)类型
10月更文挑战第24天
31 2
|
6月前
|
存储 安全 Swift
【Swift开发专栏】Swift中的集合类型:数组、字典与集合
【4月更文挑战第30天】本文探讨Swift的三种内置集合类型:数组、字典和集合。数组是有序元素集合,支持动态大小调整和类型安全;字典是无序键值对,适用于快速查找;集合是无序不重复元素集合,适合检查元素存在性和集合运算。理解这些特性和用法能提升Swift编程效率。
69 1
|
6月前
|
安全 Swift
【Swift开发专栏】Swift中的可选类型与解包
【4月更文挑战第30天】Swift的可选类型(Optional)用于表示变量可能无值,如用户未填写表单或空服务器数据。可选类型用问号(?)标记,状态可为包含值或nil。解包包括强制解包(!,可能触发运行时错误)、可选绑定(在if/while中安全解包)和隐式解包(声明时带!,使用时不需显式解包)。高级用法包括可选链式调用、空合并操作符(??)和可选类型比较。理解并恰当使用这些概念能提升代码的健壮性和安全性。
66 1
|
6月前
Swift4.0判断本函数是否在其它类有相同的方法
Swift4.0判断本函数是否在其它类有相同的方法
43 0
|
6月前
|
安全 Swift
Swift 语言:什么是可选类型(Optional)?如何处理可选类型的安全解包?
Swift的可选类型是处理值可能缺失的类,用?表示。它们能表示有值或无值状态。安全解包用`if let`或`guard let`避免崩溃,而强制解包`!`则风险较高,若值为`nil`会触发运行时错误。
47 0
|
6月前
|
存储 Swift 索引
在 Swift 编程语言中,集合类型 `Set`
在 Swift 编程语言中,集合类型 `Set`
65 1