协议扩展与类型扩展
对比协议扩展(为协议添加默认实现,甚至可以有条件地添加)与类型扩展(为一个具体类型添加 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 反馈 — 无需本地设置。