Swift 泛型
Swift 中的泛型(Generics)是一个功能强大且灵活的特性,它使你能够创建适用于任何类型的通用和可重用的函数和数据类型。通过使用泛型,你可以编写出更具通用性和适应性的代码,而无需编写多个版本的相同函数或类型,应用于不同的数据类型。泛型的一个典型的使用场景是 Swift 标准库中的 Array
和 Dictionary
类型,这些类型都使用泛型使其可以存储任意类型的元素。
泛型函数
以下是一个简单的泛型函数示例:
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
在这个函数中,<T>
是一个占位符类型,表示函数可以接收任何类型的参数,只要这两个参数是相同的类型。你可以使用 swapTwoValues
函数来交换任何两个同类型的值,而不需要为每种特定类型编写一个新函数。
泛型类型
泛型也可以用于定义自定义类型,如类、结构和枚举,例如:
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
}
上面的 Stack
结构可以用于存储任何类型的值,其类型在创建 Stack
实例时被指定。
类型约束
有时需要对泛型类型施加约束,使其符合某个特定的协议或者类。可以使用类型约束来实现:
func findIndex<T: Equatable>(of valueToFind: T, in array: [T]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
在这个例子中,T: Equatable
约束了这个泛型函数,只能被实现了 Equatable
协议的类型调用,这是因为函数内部使用了 ==
操作符。
关联类型
对于协议,也可以使用泛型特性,即关联类型。关联类型允许协议中某个类型在协议的定义中充当占位符。可以为协议声明一个或多个关联类型:
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
}
任何采用 Container
协议的类型都必须指定一个特定的 Item
类型以及实现相应的方法和属性。
Swift 泛型通过其灵活性和强大的功能帮助开发者编写出简洁、易维护且性能良好的代码,是其语言特性中极为重要的一部分。