泛型
泛型代码让你能根据自定义的需求,编写出适用于任意类型的、灵活可复用的函数及类型。你可避免编写重复的代码,而是用一种清晰抽象的方式来表达代码的意图。
泛型是 Swift 最强大的特性之一,很多 Swift 标准库是基于泛型代码构建的。实际上,即使你没有意识到,你也一直在语言指南中使用泛型。例如,Swift 的
Array
和 Dictionary
都是泛型集合。你可以创建一个 Int
类型数组,也可创建一个 String
类型数组,甚至可以是任意其他 Swift 类型的数组。同样,你也可以创建一个存储任意指定类型的字典,并对该类型没有限制。下面是一个标准的非泛型 函数
swapTwoInts(_:_:)
,用来交换两个 Int
值:func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
swapTwoInts(_:_:)
函数将 b
的原始值换成了 a
,将 a
的原始值换成了 b
,你可以调用这个函数来交换两个 Int
类型变量:var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// 打印“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
)。在实际应用中,通常需要一个更实用更灵活的函数来交换两个任意类型的值,幸运的是,泛型代码帮你解决了这种问题。(这些函数的泛型版本已经在下面定义好了。)
注意在上面三个函数中,a
和b
类型必须相同。如果a
和b
类型不同,那它们俩就不能互换值。Swift 是类型安全的语言,所以它不允许一个String
类型的变量和一个Double
类型的变量互换值。试图这样做将导致编译错误。
泛型函数可适用于任意类型,下面是函数
swapTwoInts(_:_:)
的泛型版本,命名为 swapTwoValues(_:_:)
:func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
swapTwoValues(_:_:)
和 swapTwoInts(_:_:)
函数体内容相同,它们只在第一行不同,如下所示:func swapTwoInts(_ a: inout Int, _ b: inout Int)
func swapTwoValues<T>(_ a: inout T, _ b: inout T)
泛型版本的函数使用
占位符