0Pricing
Swift Academy · 课时

协议扩展与类型扩展

对比协议扩展(为协议添加默认实现,甚至可以有条件地添加)与类型扩展(为一个具体类型添加 API)。理解分派行为和约束。

协议扩展与类型扩展 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 2 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 3 节课。

概述

目标:了解何时使用协议扩展(为所有遵循者提供默认行为),何时使用类型扩展(为一个具体类型提供编程接口)。本课还会介绍分派规则。

协议与遵循

协议声明要求。类型通过实现这些要求来遵循协议。

protocol Greeter {
    func greet() -> String
}
struct Person: Greeter {
    var name: String
    func greet() -> String { "Hi, I'm \\(name)" }  // concrete requirement impl
}
print(Person(name: "Ada").greet())

通过协议扩展提供默认实现

协议扩展可以提供默认实现,所有遵循协议的类型都会使用这些实现,除非它们提供了自己的实现。

protocol Describable {
    func describe() -> String
}
extension Describable {
    // default for ALL conformers until they override
    func describe() -> String { "No description" }
}

struct Car: Describable { }             // uses default
struct Book: Describable {
    func describe() -> String { "A book" } // custom override
}
print(Car().describe(), Book().describe())

类型扩展编程接口

类型扩展可以向一个具体类型添加方法/计算属性,但不能添加存储属性。

struct Point { var x: Int; var y: Int }

extension Point {
    // add helper just to Point
    var lengthSquared: Int { x*x + y*y }
    func moved(dx: Int, dy: Int) -> Point { Point(x: x+dx, y: y+dy) }
}
let p = Point(x: 2, y: 3)
print(p.lengthSquared, p.moved(dx: 1, dy: -1))

条件扩展

在协议扩展上使用条件子句,可以向部分遵循协议的类型添加行为。

protocol Summable { }
extension Int: Summable { }
extension Array where Element: Summable {
    // only for arrays whose elements conform to Summable
    func joinedCount() -> Int { self.count }
}
print([1,2,3].joinedCount())   // works (Int conforms)
 // print(["a","b"].joinedCount()) // not available

分派行为概述

经验法则:如果某个方法是协议要求,并且遵循协议的类型实现了它,则类型的实现优先(类似动态分派)。仅在协议扩展中添加、而非协议要求的方法,则使用静态分派。

protocol Speaker { func speak() -> String }
extension Speaker { func speak() -> String { "default" } }

struct Cat: Speaker { }
struct Dog: Speaker {
    func speak() -> String { "woof" } // requirement impl overrides default
}

let s1: Speaker = Cat()
let s2: Speaker = Dog()
print(s1.speak()) // "default" (uses default impl)
print(s2.speak()) // "woof" (Dog provides requirement impl)

let c = Cat()
print(c.speak())  // "default" via extension on protocol

协议扩展与类型扩展

快速检查:两者的关键区别是什么?

回顾

回顾:使用协议扩展提供可复用的默认实现(也可以是有条件的),使用类型扩展扩展一个类型。请记住分派规则:对要求的实现会覆盖扩展中的默认方法。

常见问题解答

「协议扩展与类型扩展」课时是免费的吗?

是的 — 「协议扩展与类型扩展」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 3 节课。

「协议扩展与类型扩展」这节课中我会学到什么?

对比协议扩展(为协议添加默认实现,甚至可以有条件地添加)与类型扩展(为一个具体类型添加 API)。理解分派行为和约束。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 3 节。

「协议扩展与类型扩展」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 协议与扩展基础
  2. 协议扩展与类型扩展
  3. 静态要求与实例要求
← 返回 Swift Academy