-
泛型所解决的问题
先来看几个函数:
func swapTwoInts(_ a: inout Int, _ b: inout Int) { let temporaryA = a
a= b
b = temporaryA
}
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
}
上面三个函数的功能都是相同的,即交换两个变量的值,唯一不同之处就在于传入的变量类型不同,分别是 Int
、 String
和 Double
。而实际应用中,为了实现相同的功能却要实现多个函数,这显然不是我们最想要的,幸运的是,泛型代码很好的解决了这个问题。
注意:
在上面三个函数中,a
和b
类型相同。如果a
和b
类型不同,那它们俩就不能互换值。Swift
是类型安全的语言,所以它不允许一个String
类型的变量和一个Double
类型的变量互换值。试图这样做将导致编译错误。
泛型代码实现:
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a= b
b = temporaryA
}
这个函数的泛型版本使用了占位类型名(在这里用字母 T
来表示)来代替实际类型名(例如 Int
、String
或 Double
)。占位类型名没有指明 T
必须是什么类型,但是它指明了 a
和 b
必须是同一类型 T
,无论 T
代表什么类型。只有swapTwoValues(_:_:)
函数在调用时,才能根据所传入的实际类型决定 T
所代表的类型。
另外一个不同之处在于这个泛型函数名( swapTwoValues(_:_:)
)后面跟着占位类型名( T
),并用尖括号括起 来( <T>
)。这个尖括号告诉 Swift
那个 T
是 swapTwoValues(_:_:)
函数定义内的一个占位类型名,因此 Swift
不会去查找名为 T
的实际类型。