Swift中的泛型:为何需要及如何使用

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:什么是泛型以及它们在 Swift 中为何重要



泛型是 Swift 语言中最强大、最优雅的特性之一。它允许你编写灵活、可复用的代码,这些代码能适用于任何数据类型,同时保持强类型。如果你曾经使用过 Array<Int>、Dictionary<String, Any> 或 Optional<T> —— 那么你已经接触过泛型了。



在本文中,我们将探讨为什么 Swift 需要泛型,它们在实际中如何工作,并展示适用于 iOS/macOS 开发的示例。无论你是初学者还是希望梳理知识体系的经验丰富的开发者,这些内容都将对你有帮助。



1. 为什么 Swift 需要泛型?



泛型的主要目的是避免代码重复并提高安全性。设想你需要编写一个交换两个值的函数。如果没有泛型,你将不得不为 Int、String、Double 等类型分别创建不同的函数:



func swapInts(_ a: inout Int, _ b: inout Int) {    let temp = a    a = b    b = temp}

func swapStrings(_ a: inout String, _ b: inout String) { let temp = a a = b b = temp}


使用泛型,这个任务可以通过一个通用函数来解决:



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

var x = 10, y = 20swapValues(&x, &y) // x = 20, y = 10

var name1 = "Alice", name2 = "Bob"swapValues(&name1, &name2) // name1 = "Bob", name2 = "Alice"


泛型的优势:

  • 代码复用性:一个函数/类型适用于任何数据类型。
  • 类型安全:编译器在编译时检查类型,消除了运行时错误。
  • 性能:Swift 中的泛型通过编译时多态(特化)实现,因此没有类型转换的开销。
  • 可读性:代码变得更加抽象和简洁。


2. 泛型函数:语法与示例



泛型函数使用尖括号 <T> 声明,其中 T 是类型的占位符。你可以使用任何标识符:T、Element、Value 等。



基础示例:查找元素的索引



func findIndex<T: Equatable>(of value: T, in array: [T]) -> Int? {    for (index, item) in array.enumerated() {        if item == value {            return index        }    }    return nil}

let numbers = [1, 3, 5, 7, 9]if let index = findIndex(of: 5, in: numbers) { print("Index of number 5: \\(index)") // Index of number 5: 2}


注意约束 <T: Equatable>。这是一个 类型约束。它告诉编译器:"T 必须遵循 Equatable 协议"。如果没有这个约束,== 运算符将不可用。



多个类型参数



你可以使用多个类型参数:



func combine<T, U>(_ first: T, with second: U) -> String {    return "\\(first) + \\(second)"}

let result = combine(42, with: "answer")print(result) // 42 + answer


3. 泛型类型:创建泛型结构体和类



泛型不仅适用于函数,也适用于类型。最流行的例子是 Array<Element>。让我们创建自己的泛型结构体——栈(后进先出):



struct Stack<Element> {    private var items: [Element] = []        mutating func push(_ item: Element) {        items.append(item                

博客

书籍推荐