Swift

泛型

本文详细介绍了 Swift 中的泛型,包括泛型函数、泛型类型、类型约束、关联类型以及泛型 Where 子句。

泛型(Generics)是 Swift 最强大的特性之一,许多 Swift 标准库是通过泛型代码构建的。泛型代码让你能够编写灵活的、可重用的函数和类型,这些函数和类型可以根据你的需求与任何类型一起工作,从而避免重复代码。

泛型函数 (Generic Functions)

泛型函数可以适用于任何类型。下面是一个交换两个值的泛型函数示例:

func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
// someInt 现在是 107, anotherInt 现在是 3

var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// someString 现在是 "world", anotherString 现在是 "hello"

在这个例子中,T 是一个占位符类型名称,它并不表示任何具体的类型,而是表示 ab 必须是同一种类型 T

泛型类型 (Generic Types)

除了泛型函数,Swift 还允许你定义自己的泛型类型。这些通常是集合类型,如 Stack(栈)。

struct Stack<Element> {
    var items: [Element] = []
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
}

var stackOfStrings = Stack<String>()
stackOfStrings.push("uno")
stackOfStrings.push("dos")

类型约束 (Type Constraints)

有时,你可能需要对泛型函数或泛型类型可以接受的类型强制施加某些约束。类型约束指定类型参数必须继承自特定类,或遵循特定协议或协议组合。

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 协议的类型 T”。

关联类型 (Associated Types)

定义协议时,有时声明一个或多个关联类型作为协议定义的一部分是非常有用的。关联类型为协议中的某个类型提供了一个占位符名称。

protocol Container {
    associatedtype Item
    mutating func append(_ item: Item)
    var count: Int { get }
    subscript(i: Int) -> Item { get }
}

struct IntStack: Container {
    // IntStack 的原始实现部分
    var items: [Int] = []
    mutating func push(_ item: Int) {
        items.append(item)
    }
    mutating func pop() -> Int {
        return items.removeLast()
    }
    
    // Container 协议的实现部分
    typealias Item = Int
    mutating func append(_ item: Int) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Int {
        return items[i]
    }
}

泛型 Where 子句 (Generic Where Clauses)

类型约束允许你定义泛型函数或类型必须满足的要求。泛型 where 子句让你能够要求关联类型必须遵循特定协议,或者特定的类型参数和关联类型必须相同。

func allItemsMatch<C1: Container, C2: Container>
    (_ someContainer: C1, _ anotherContainer: C2) -> Bool
    where C1.Item == C2.Item, C1.Item: Equatable {
        
    // 检查两个容器是否包含相同数量的元素
    if someContainer.count != anotherContainer.count {
        return false
    }
    
    // 检查每一对元素是否相等
    for i in 0..<someContainer.count {
        if someContainer[i] != anotherContainer[i] {
            return false
        }
    }
    
    // 所有元素都匹配
    return true
}
在 GitHub 上编辑

上次更新于