[Swift]17、泛型

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()
    }
}

你可能感兴趣的:([Swift]17、泛型)