Swift 的抽象三件套
学完基础语法,想让代码更通用、更解耦,就绕不开协议、泛型与构建器模式。协议定义"能做什么",泛型定义"对什么类型都能用",构建器模式定义"怎么一步步组装对象"。三者搭起来,就是 Swift 高阶写法。
好的抽象:定义稳定的能力契约,让具体实现可替换、可复用。
这篇把这三件套落到实处。
协议:定义能力契约
协议只声明方法与属性,不写实现。类、结构体去遵守它,就承诺具备这些能力。面向协议编程里,你先设计协议,再让具体类型实现,上层依赖协议而非具体类。
protocol Identifiable {
var id: String { get }
}
struct User: Identifiable { let id: String }
任何 Identifiable 都能被统一处理,不管它是 User 还是 Article。
协议扩展与默认实现
Swift 的杀手锏:给协议写扩展,提供默认实现。遵守协议的类型自动白拿这套方法,省去每个类型重复写。这是"面向协议"比传统接口更强大的地方。
协议扩展速记
- 默认实现协议扩展提供通用方法。
- 条件扩展配合 where 只给满足约束的类型实现。
- 复用一处实现,多类型共享。
泛型:写出一次通用的代码
同一个函数要能处理 Int、String、任意类型,用泛型占位。下面的交换函数不挑类型:
func swapTwo<T>(_ a: inout T, _ b: inout T) {
let t = a; a = b; b = t
}
T 是占位类型,调用时由编译器推断具体类型。
泛型约束与 where
泛型不限制类型时什么都做不了——你不能对任意 T 比较大小。用约束或 where 子句限定 T 必须遵守某个协议,就能调用协议里的方法。这是泛型真正好用的关键。
func biggest<T: Comparable>(_ a: T, _ b: T) -> T {
a >= b ? a : b
}
限定 T 可比较,才能用大于号。
构建器模式:链式组装
对象参数多时,与其传一大串初始化参数,不如提供一个构建器:一步一步设属性,最后 build() 出对象。链式写法清晰、可选参数自然。SwiftUI 的 View 修饰符本质就是这种构建器思想。
实战:一个可复用的网络请求构建器
用协议抽象"可请求",用泛型处理不同返回类型,用构建器组装 URL。
class RequestBuilder {
private var path = ""
private var method = "GET"
func path(_ p: String) -> Self { path = p; return self }
func method(_ m: String) -> Self { method = m; return self }
func build() -> URLRequest { /* 组装 */ }
}
调用时链式:builder.path("/news").method("POST").build()。协议定契约、泛型管类型、构建器管组装——三者合起来,Swift 代码就能既通用又干净。