1、泛型函数
泛型可以将类型参数化,提高代码复用率,减少代码量
func swapValue(_ a: inout T, _ b: inout T) {
(a, b) = (b, a)
}
var fn: (inout Int, inout Int) -> () = swapValue
var n1 = 20
var n2 = 10
swapValue(&n1, &n2)
fn(&n1, &n2)
汇编的实现方式
// 传入类型
0x100003134 <+132>: leaq 0x90c5(%rip), %rax ; Demo.n1 : Swift.Int
0x10000313b <+139>: leaq 0x90c6(%rip), %rcx ; Demo.n2 : Swift.Int
// 将metadata信息传入到rdx
0x100003142 <+146>: movq 0x4f27(%rip), %rdx ; (void *)0x00007fff81555c80: type metadata for Swift.Int
// 传入两个参数到函数
0x100003149 <+153>: movq %rax, %rdi
0x10000314c <+156>: movq %rcx, %rsi
0x10000314f <+159>: callq 0x100003240 ; Demo.swapValue(inout T, inout T) -> () at main.swift:10
2、class泛型类型
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 inStack = Stack()
3、struct类型的泛型
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 }
}
4、enum类型的泛型
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")
5、关联类型
关联类型的作用:给协议中用到的类型定义一个占位名称
协议中可以拥有多个关联类型
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 = [Element]()
func push(_ element: Element) { elements.append(element) }
func pop()-> Element { elements.removeLast() }
func top() -> String { elements.last! }
func size() -> Int { elements.count }
}
6、类型约束
protocol Runnable { }
class Person { }
func swapValues(_a inout T, _ b inout T) {
(a, b) = (b, a)
}
7、协议类型的注意点
protocol Runnable {
associatedtype Speed
var speed: Speed { get }
}
class Person: Runnable {
var speed: Double { 0.0 }
}
class Car: Runnable {
var speed: Int { 0 }
}
// 泛型解决
// ?????
func get(_ type: Int) -> T {
if type == 0 {
return Person() as! T
}
return Car() as! T
}
var r1: Person = get(0)
var r2: Car = get(1)
// 不透明类型
// 使用 some 关键字声明一个不透明类型
// some限制只能返回一种类型
func get1(_ type: Int) -> some Runnable {
return Car()
}
8、some
some除了用在返回值类型上,一般还可以用在属性类型上
protocol Runnable {
associatedtype Speed
}
class Dog: Runnable {
typealias Speed = Double
}
class Person {
var pet: some Runnable {
return Dog()
}
}