- 泛型函数
- 泛型类型
- 泛型扩展
如下面的代码:比较a, b两个是否相等,a和b的数据类型不确定
思考: 能否用一个函数,根据实际传入的参数类型而进行相应类型的比较,即适用于多种类型的比较。泛型提供了这种可能性。
func isEqualsInt(a: Int, b: Int) -> Bool {
return (a == b)
}
func isEqualsDouble(a: Double, b: Double) ->Bool {
return (a == b)
}
func isEqualsString(a: String, b: String) -> Bool {
return (a == b)
}
泛型函数
func isEquals<T>(a: T, b: T) -> Bool {
return (a == b)
}
在函数名isEquals后面添加<T>,参数的类型也被声明为T,T称为占位符,函数在每次调用时传入实际类型才能决定T所代表的类型。
注:如果有多种类型,可以使用其他大写字母,一般情况下大家习惯于使用字母U,但也可以使用其他的字母。
使用泛型函数
func isEquals<T>(a: T, b: T) -> Bool的函数在编译时会有错误发生,这是因为并不是所有的类型T都有“可比性”,T必须遵从Comparable协议的类型。Comparable协议表示"可比性",在Swift中基本数据类型以及字符串都是遵从Comparable协议的。
所以对泛型类型要有限制,这个限制就叫作泛型约束。
///泛型约束
func isEquals<T: Comparable>(a: T, b: T) -> Bool {
return (a == b)
}
let n1 = 200
let n2 = 100
print(isEquals(a: n1, b: n2))
let s1 = "ABC1"
let s2 = "ABC1"
print(isEquals(a: s1, b: s2))
多类型参数
多个占位符(多个占位符之间用逗号,“,”分隔),示例如下:func isEquals<T, U>(a: T, b:U) -> Bool{...}
占位符不仅可以替代参数类型,还可以替代返回值类型,示例代码如下:func isEquals<T>(a: T, b:T) -> T {...}
///泛型: 多类型参数
func isEquals<T, U>(a: T, b: U) -> T? {
return nil
}
func isEquals<T, U, K>(a: T, b: U) -> K? {
return nil
}
泛型类型
泛型不仅可以在函数中使用,而且可以应用于类、结构体和枚举等类型定义,这些类型就是泛型类型。 泛型类型一般都是与集合有关的类型,如:数组、Set和字典等。
示例:
//===字符串队列====
struct StringQueue {
var items = [String]()
mutating func queue(item: String) {
items.append(item)
}
mutating func dequeue() -> String? {
if items.isEmpty {
return nil
}else {
return items.remove(at: 0)
}
}
}
var strQueue = StringQueue()
//入队
strQueue.queue(item: "张三")
strQueue.queue(item: "李四")
strQueue.queue(item: "王五")
strQueue.queue(item: "董六")
//出队
print(strQueue.dequeue()!) //张三
print(strQueue.dequeue()!) //李四
print(strQueue.dequeue()!) //王五
print(strQueue.dequeue()!) //董六
print(strQueue.items)
改为使用泛型实现队列,如下代码
//泛型实现队列
struct Queue<T> {
var items = [T]()
mutating func queue(item: T) {
items.append(item)
}
mutating func dequeue() -> T? {
if items.isEmpty {
return nil
}else {
return items.remove(at: 0)
}
}
}
var genericQueue = Queue<Int>()
genericQueue.queue(item: 3)
genericQueue.queue(item: 6)
genericQueue.queue(item: 9)
genericQueue.queue(item: 12)
print(genericQueue.dequeue()!)
print(genericQueue.dequeue()!)
print(genericQueue.dequeue()!)
print(genericQueue.dequeue()!)
var genericQueue2 = Queue<String>()
genericQueue2.queue(item: "a")
genericQueue2.queue(item: "b")
genericQueue2.queue(item: "c")
genericQueue2.queue(item: "d")
print(genericQueue2.dequeue()!)
print(genericQueue2.dequeue()!)
print(genericQueue2.dequeue()!)
print(genericQueue2.dequeue()!)
泛型扩展
泛型类型可以支持扩展,这种情况下定义的扩展与其他普通扩展没有区别。
///泛型扩展
struct Queue3<T> {
var items = [T]()
mutating func queue(item: T) {
items.append(item)
}
mutating func dequeue() -> T? {
if items.isEmpty {
return nil
}else {
return items.remove(at: 0)
}
}
}
//泛型扩展: 对Queue3进行扩展
extension Queue3 {
func peek(position: Int) -> T? {
if position < 0 || position > items.count {
return nil
}else {
return items[position]
}
}
}
var genericDoubleQueue = Queue3<Double>()
genericDoubleQueue.queue(item: 1.34)
genericDoubleQueue.queue(item: 2.38)
genericDoubleQueue.queue(item: 3.46)
genericDoubleQueue.queue(item: 4.57)
print(genericDoubleQueue.peek(position: 2)!) //3.46
网友评论