Published 2022-03-23

Swift - 泛型

泛型(Generics)是 Swift 中一项非常强大的功能,它允许您编写灵活、可重用的函数和类型,可以在任何数据类型上进行工作。

使用泛型,您可以定义一组通用的操作,而不必在每种数据类型上编写单独的函数或方法。这使得代码更加灵活、可读性更高、易于维护,并提高了代码的重用性。

以下是一些基本概念:

泛型函数

泛型函数是可以在不同数据类型之间共享的函数。这些函数在调用时可以指定要使用的数据类型。在 Swift 中,泛型函数可以接受任何类型的参数,包括整数、浮点数、字符串和自定义类型。

下面是一个简单的泛型函数示例:

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

在这个例子中,我们定义了一个函数 swapTwoValues,它接受两个参数 a 和 b,它们都是泛型类型 T。函数体内使用了一个临时变量 temp,来交换 a 和 b 的值。

这个函数中的 <T> 声明了一个类型参数 T,用来指定函数参数的类型。调用函数时,可以将具体的数据类型作为参数传入:

var a = 10
var b = 20
swapTwoValues(&a, &b) // a is now 20, and b is now 10

在这个示例中,我们将 a 和 b 作为参数传递给 swapTwoValues 函数,并通过引用传递(使用 & 符号)将它们作为可变参数传递。函数交换了 a 和 b 的值,所以现在 a 的值为 20,b 的值为 10。

泛型类型

泛型类型是可以用于多个不同类型的类型。使用泛型类型,可以编写通用代码,而不必为每个特定类型编写单独的代码。在 Swift 中,可以使用类、结构体和枚举来定义泛型类型。

下面是一个简单的泛型结构体示例:

struct Stack<Element> {
var items = [Element]()

    mutating func push(_ item: Element) {
        items.append(item)
    }

    mutating func pop() -> Element? {
        return items.popLast()
    }
}

在这个例子中,我们定义了一个泛型结构体 Stack,它可以用于存储任意类型的元素。该结构体包含一个数组 items,用于存储元素。结构体还包含两个方法,用于将元素添加到堆栈中和从堆栈中删除元素。

可以在创建 Stack 实例时,使用类型参数 `Element

当我们编写代码时,我们经常需要同时处理多个不同类型的值,这些类型的值可能会在未来的某个时候发生变化。使用泛型可以让我们编写出灵活的代码,可以在编译时进行类型检查,同时可以在运行时自动适应类型。

Swift 中的泛型允许我们定义通用类型和函数,可以适用于各种数据类型。这使我们可以写出更加通用和重用的代码。

在 Swift 中,我们可以通过在类型、函数或方法名称后面使用尖括号(<>)和一个或多个占位符来声明泛型。这些占位符可以用于指定类型参数,这些参数在调用函数或实例化类型时将被替换为实际类型。

以下是一个使用泛型的示例:

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

var x = 10
var y = 20

swapValues(&x, &y) // x is now 20, y is now 10

在这个例子中,我们定义了一个函数 swapValues,它使用了一个类型参数 T。在函数体内,我们声明了一个名为 temp 的临时变量,然后交换了 a 和 b 的值。由于 a 和 b 都是 inout 参数,因此它们将被修改为新的值。

我们可以使用这个函数来交换任何两个相同类型的值,例如整数、浮点数、字符串、数组等等。在调用这个函数时,我们需要提供两个相同类型的值作为参数。

泛型在 Swift 中是非常强大和灵活的,它们可以帮助我们写出高效、可维护和可重用的代码。