泛型函数可适用于任意类型,下面是函数 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)
泛型版本的函数使用占位符
类型名(这里叫做 T
),而不是 实际类型名(例如 Int
、String
或 Double
),占位符
类型名并不关心 T
具体的类型,但它要求 a
和b
必须是相同的类型,T
的实际类型由每次调用 swapTwoValues(_:_:)
来决定。
泛型函数和非泛型函数的另外一个不同之处在于这个泛型函数名(swapTwoValues(_:_:)
)后面跟着占位类型名(T
),并用尖括号括起来(``)。这个尖括号告诉 Swift 那个 T
是 swapTwoValues(_:_:)
函数定义内的一个占位类型名,因此 Swift 不会去查找名为 T
的实际类型。
swapTwoValues(_:_:)
函数现在可以像 swapTwoInts(_:_:)
那样调用,不同的是它能接受两个任意类型的值,条件是这两个值有着相同的类型。swapTwoValues(_:_:)
函数被调用时,T
所代表的类型都会由传入的值的类型推断出来。
在下面的两个例子中,T
分别代表 Int
和 String
:
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”
注意
上面定义的
swapTwoValues(_:_:)
函数是受swap(_:_:)
函数启发而实现的。后者存在于 Swift 标准库,你可以在你的应用程序中使用它。如果你在代码中需要类似swapTwoValues(_:_:)
函数的功能,你可以使用已存在的swap(_:_:)
函数。