Swift 泛型

时间:2022-07-23
本文章向大家介绍Swift 泛型,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

泛型解决的问题

下面的 swapTwoInts(::) 是一个标准的非泛型函数,用于交换两个 Int 值:

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

这个函数用输入输出形式参数来交换 a 和 b 的值。

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now (someInt), and anotherInt is now (anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"

swapTwoInts(::) 函数很实用,但是它只能用于 Int 值。如果你想交换两个 String 值,或者两个 Double 值,你只能再写更多的函数,比如下面的 swapTwoStrings(::) 和 swapTwoDoubles(::) 函数:

func swapTwoStrings(_ a: inout String, _ b: inout String) {
    let temporaryA = a
    a = b
    b = temporaryA
}

func swapTwoDoubles(_ a: inout Double, _ b: inout Double) {
    let temporaryA = a
    a = b
    b = temporaryA
}

你可能已经注意到了, swapTwoInts(::) 、 swapTwoStrings(::) 、 swapTwoDoubles(::) 函数体是一样的。唯一的区别是它们接收值类型不同( Int 、 String 和 Double )。

泛型函数

泛型函数可以用于任何类型。这里是上面提到的 swapTwoInts(::) 函数的泛型版本,叫做 swapTwoValues(::) :

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

swapTwoValues(::) 和 swapTwoInts(::) 函数体是一样的。但是, swapTwoValues(::) 和 swapTwoInts(::) 的第一行有点不一样。下面是首行的对比:

func swapTwoInts(_ a: inout Int, _ b: inout Int)
func swapTwoValues<T>(_ a: inout T, _ b: inout T)

泛型版本的函数用了一个占位符类型名(这里叫做 T ),而不是一个实际的类型名(比如 Int 、 String 或 Double )。占位符类型名没有声明 T 必须是什么样的,但是它确实说了 a 和 b 必须都是同一个类型 T ,或者说都是 T 所表示的类型。替代 T 实际使用的类型将在每次调用 swapTwoValues(::) 函数时决定。

其他的区别是泛型函数名( swapTwoValues(::) )后面有包在尖括号( <T> )里的占位符类型名( T )。尖括号告诉Swift, T 是一个 swapTwoValues(::) 函数定义里的占位符类型名。因为 T 是一个占位符,Swift 不会查找真的叫 T 的类型。

现在,可以用调用 swapTwoInts 的方式来调用 swapTwoValues(::) 函数,除此之外,可以给函数传递两个任意类型的值,只要两个实参的类型一致即可。每次调用 swapTwoValues(::) ,用于 T 的类型会根据传入函数的值类型自动推断。

在下面的两个例子中, T 分别被推断为 Int 和 String :

var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
// someInt is now 107, and anotherInt is now 3
 
var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// someString is now "world", and anotherString is now "hello"

比较两个值的最小值

 func myMin<T: Comparable>(_ a:T, _ b: T) -> T {
        return a < b ? a : b
  }
print("Min is:", myMin(2, 21))
// Min is: 2