知识卡片
协议不能泛型化改用关联类型
内容
Swift的协议本身不能像类型一样带尖括号占位参数(没有protocol Container<T>这种写法),但可以在协议内部用associatedtype声明一个占位类型,交给每个符合协议的具体类型自己决定填什么(如IteratorProtocol要求associatedtype Element,next()返回Element?;具体类型可以显式提供typealias Element = T,也可以让编译器从next()的实现签名反推出Element是什么)。这和[[泛型用占位类型换取跨类型复用而不丢失类型安全]]里泛型类型的占位类型方向相反:泛型类型的占位类型由调用方在使用处指定(Stack<Int>),关联类型则由遵从协议的类型自己在实现时锁定,调用方无从干预。这个不对称性是很多人初学Swift协议时的困惑点,也是Sequence、Collection等标准库核心协议得以既通用又类型安全的关键机制。
参考来源
《Swift编程权威指南》第22章《泛型》