泛型的主要目的1.提高利用率2.减少代码量
基本的泛型函数
var a = 1,b = 5
//func exchange<T>(_ a:inout T,_ b :inout T) {
func exchange<ALL>(_ a:inout ALL,_ b :inout ALL) {
( a , b ) = ( b , a )
}
exchange(&a, &b)
print("a:\(a),b:\(b)") //a:5,b:1
var s1 = "123",s2 = "yokan"
exchange(&s1, &s2)
print("s1:\(s1),s2:\(s2)") //s1:yokan,s2:123
这个<ALL>里面的值随便定义了ALL也行T也行,一般来说是写T,然后这么定义后基本就啥类型都支持了
泛型函数会在调用函数的时候多传入一个rdx,多个类型参数,实际上调用的函数还是同一个,用类型参数在里面做区别
泛型在结构体,类,枚举使用的区别
struct Stack <E>{
var stacks = [E]()
mutating func push(element:E) {
stacks.append(element)
}
mutating func pop() -> E
{
stacks.removeLast()
}
mutating func top() -> E
{
stacks.last!
}
mutating func count() -> Int
{
stacks.count
}
}
泛型在类,结构体的定义大致如图,类的话不用写mutating,另外就是调用的时候
class Stack <E> {
var stacks = [E]()
init(_ elements:E) {
stacks.append(elements)
}
func push(element:E) {
stacks.append(element)
}
func pop() -> E
{
stacks.removeLast()
}
func top() -> E
{
stacks.last!
}
func count() -> Int
{
stacks.count
}
}
var s = Stack(10.0)
比如有一个初始化器,人为的传入了值,编译器就能明白这是个Double类型
如果没有具体的初始化器,就必须指定一个类型
var s = Stack<Any>()
//var s = Stack<Double>()
具体是什么类型就指定什么类型,如果还是不确定就用Any,这里不能用E,上面的E是泛型,就代表随便什么类型,这里则必须指定官方支持的类型,比如还是什么类型都行,就传入Any
泛型在枚举来说,定义是一样的
enum Score<T> {
case Point(T)
case Grade(String)
}
上述代码可以看到,定义是差不多的,也是<T>声明了,里面就可以使用T来当做泛型,区别在于初始化
let point = Score.Grade("A")
这样初始化是肯定会报错的,因为T是什么并不清楚,不清楚也就不知道怎么分配内存
let point = Score<Any>.Grade("A")
和类与结构体类似,这个T也必须指定类型,泛型可以是Any,但不能是Swift完全不能支持的类型