Self 要求与 Equatable 设计
了解使用 Self 的协议,以及 Equatable 和 Comparable 如何利用它们。
Self 要求与 Equatable 设计 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
欢迎
`Self` 在协议中指遵循该协议的具体类型。它让 `Equatable` 和 `Comparable` 这样的协议能够安全地处理异构类型。
自身类型作为参数类型
```swift
protocol Equatable {
static func == (lhs: Self, rhs: Self) -> Bool
}
```
`Self` 表示两个参数必须是*同一种*具体类型。您不能通过这个协议比较 `Int` 和 `String`。
遵循等价比较协议
```swift
struct Point: Equatable {
var x: Double
var y: Double
// Auto-synthesised:
// static func == (lhs: Point, rhs: Point) -> Bool
// { lhs.x == rhs.x && lhs.y == rhs.y }
}
print(Point(x:1,y:2) == Point(x:1,y:2)) // true
```
使用自身类型实现可比较
```swift
struct Version: Comparable {
let major, minor, patch: Int
static func < (lhs: Version, rhs: Version) -> Bool {
(lhs.major, lhs.minor, lhs.patch) < (rhs.major, rhs.minor, rhs.patch)
}
}
let v1 = Version(major:1,minor:2,patch:0)
let v2 = Version(major:2,minor:0,patch:0)
print(v1 < v2) // true
```
自身类型作为返回类型
```swift
protocol Clonable {
func clone() -> Self
}
class Animal: Clonable {
var name: String = ""
required init() {}
func clone() -> Self { type(of: self).init() }
}
```
返回类型中的 `Self` 表示子类会返回自身类型,而不是 `Animal`。
带有自身类型要求的协议(PAT)
```swift
protocol Scalable {
func scaled(by factor: Double) -> Self
}
struct Size: Scalable {
var w, h: Double
func scaled(by f: Double) -> Size { Size(w: w*f, h: h*f) }
}
```
可哈希:自身类型与等价比较
```swift
struct Color: Hashable {
var r, g, b: UInt8
// Auto-synthesised: func hash(into:) and ==
}
var palette: Set = []
palette.insert(Color(r:255,g:0,b:0))
```
`Hashable` 要求同时遵循 `Equatable`;对于简单结构体,这两者都会自动合成。
带有自身类型要求的协议不能直接用作存在类型
```swift
// Before Swift 5.7:
var shapes: [Equatable] = [] // ❌ Equatable has Self requirement
// After Swift 5.7 with 'any':
var boxes: [any Equatable] = [] // ⚠️ limited API
```
`any` 关键字会显式选择存在类型装箱。
自动合成的前提条件
自动合成 `Equatable`/`Hashable`/`Comparable` 需要满足以下条件:
• 所有存储属性都遵循同一个协议
• 枚举成员(包括关联值)都遵循该协议
```swift
struct Pair: Equatable { var a, b: T }
// Equatable synthesised automatically
```
自定义等价比较实现
```swift
struct Person: Equatable {
var id: UUID
var name: String
// Only compare by id, ignore name:
static func == (lhs: Person, rhs: Person) -> Bool {
lhs.id == rhs.id
}
}
```
快速检查
在协议中,`Self` 指什么?
回顾
要点回顾:
• `Self` = 遵循协议的具体类型
• `Equatable`、`Comparable` 和 `Hashable` 都使用 `Self`
• Swift 会为简单的结构体和枚举自动合成这些实现
• 返回类型中的 `Self` 可以提供保留类型信息的接口
• 带有 Self 要求的协议在用作存在类型时需要使用 `any`(Swift 5.7+)
下一节:面向协议的设计原则。
常见问题解答
「Self 要求与 Equatable 设计」课时是免费的吗?
是的 — 「Self 要求与 Equatable 设计」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「Self 要求与 Equatable 设计」这节课中我会学到什么?
了解使用 Self 的协议,以及 Equatable 和 Comparable 如何利用它们。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「Self 要求与 Equatable 设计」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。