Generics(泛型)允许定义灵活且可重用的函数和类型。Swift 的关键特性是保持类型安全:编译器在编译时检查与具体类型的操作。可以通过 where 条件、继承协议及其组合来限制泛型类型。
代码示例:
func swapValues<T>(_ a: inout T, _ b: inout T) { let temp = a a = b b = temp } protocol Drawable { func draw() } func drawAll<T: Drawable>(_ items: [T]) { for item in items { item.draw() } } // 基于协议和 where 条件的限制 func compareValues<T: Equatable>(_ a: T, _ b: T) -> Bool { return a == b }
泛型函数可以作为重载函数吗?编译器如何选择所需的实现?
答案: 是的,泛型函数可以与普通函数和其他泛型函数重载。编译器会尝试选择最具体的实现。示例:
func printValue(_ value: Int) { print("Int: \(value)") } func printValue<T>(_ value: T) { print("Generic: \(value)") } printValue(5) // Int: 5 printValue("Swift") // Generic: Swift
故事
团队编写了一个泛型数组扩展以查找索引,却忘记通过 Equatable 限制类型。这导致在尝试在包含非 Equatable 元素的数组上应用扩展时出现编译错误。
故事
在项目中尝试实现泛型对象缓存而不限制类型。结果,在运行时尝试向下转型时出现崩溃——真正的安全使用可以通过带有 associated type 的协议和约束实现。
故事
开发人员实现了泛型类,但在继承和重写时忘记了需要指定继承者的完整泛型参数。因此代码无法编译,必须全面重建类型层次结构。