泛型可以将类型参数化,提高代码复用率,减少代码量
func swapValues
(_ a: inout T, _ b: inout T)
func swapValues(_ a: inout T, _ b: inout T)
{
(a, b) = (b, a)
}
var i1 = 10
var i2 = 20
swapValues(&i1, &i2)
var d1 = 10.0
var d2 = 20.0
swapValues(&d1, &d2)
struct Date {
var year = 0, month = 0, day = 0
}
var dd1 = Date(year: 2011, month: 9, day: 10) var dd2 = Date(year: 2012, month: 10, day: 11) swapValues(&dd1, &dd2)
泛型函数赋值给变量
var fn: (Int, Double) -> () = test
func test(_ t1: T1, _ t2: T2) {}
var fn: (Int, Double) -> () = test
class Stack {
var elements = [E]()
func push(_ element: E) { elements.append(element) } func pop() -> E { elements.removeLast() }
func top() -> E { elements.last! }
func size() -> Int { elements.count }
}
var stack = Stack()
stack.push(11)
stack.push(22)
stack.push(33)
print(stack.top()) // 33
print(stack.pop()) // 33
print(stack.pop()) // 22
print(stack.pop()) // 11
print(stack.size()) // 0
泛型类继承
class SubStack : Stack {}
结构体泛型,更改结构体元素需要关键字mutating
struct Stack {
var elements = [E]()
mutating func push(_ element: E) { elements.append(element) }
mutating func pop() -> E { elements.removeLast() }
func top() -> E { elements.last! }
func size() -> Int { elements.count }
}
枚举泛型,调用时必须明确枚举泛型类型
Score
.grade("A")
enum Score {
case point(T)
case grade(String)
}
let score0 = Score.point(100) let score1 = Score.point(99)
let score2 = Score.point(99.5) let score3 = Score.grade("A")
协议中不能直接使用泛型,需要使用关联类型,关键字associatedtype
关联类型的作用:给协议中用到的类型定义一个占位名称
协议中可以拥有多个关联类型
定义协议associatedtype Element // 关联类型
protocol Stackable {
associatedtype Element // 关联类型
mutating func push(_ element: Element)
mutating func pop() -> Element
func top() -> Element
func size() -> Int
}
类遵守协议
class StringStack : Stackable {
// 给关联类型设定真实类型
// typealias Element = String
var elements = [String]()
func push(_ element: String) { elements.append(element) }
func pop() -> String { elements.removeLast() }
func top() -> String { elements.last! }
func size() -> Int { elements.count } }
var ss = StringStack()
ss.push("Jack")
ss.push("Rose")
}
类使用泛型并遵守协议
class Stack : Stackable {
// typealias Element = E
var elements = [E]()
func push(_ element: E) {
elements.append(element) }
func pop() -> E { elements.removeLast() } func top() -> E { elements.last! }
func size() -> Int { elements.count }
}
同时满足条件的类型
protocol Runnable { }
class Person { }
func swapValues(_ a: inout T, _ b: inout T) {
(a, b) = (b, a)
}
关联类型约束Equatable
protocol Stackable {
associatedtype Element: Equatable
}
class Stack : Stackable { typealias Element = E }
条件约束
返回值后面where约束
func equal(_ s1: S1, _ s2: S2) -> Bool where S1.Element == S2.Element, S1.Element : Hashable {
return false
}
var stack1 = Stack()
var stack2 = Stack()