精通Swift(17)- 泛型

泛型(Generics)

    泛型可以将类型参数化,提高代码复用率,减少代码量

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)

-------------

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 }

}

class SubStack : Stack {}

------------------

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 }

}

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

-------------------

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")

关联类型(Associated Type)

    关联类型的作用:给协议中用到的类型定义一个占位名称

    协议中可以拥有多个关联类型

protocol Stackable {

    associatedtype Element // 关联类型 

    mutating func push(_ element: Element) 

    mutating func pop() -> Element

    func top() -> Element

    func size() -> Int

}

------------------------

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 }

}

-----------------------------

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")

类型约束

protocol Runnable { }

class Person { }

func swapValues(_ a: inout T, _ b: inout T) {

    (a, b) = (b, a)

}

-----------

protocol Stackable {

    associatedtype Element: Equatable

}

class Stack : Stackable { typealias Element = E }

------

func equal(_ s1: S1, _ s2: S2) -> Bool where S1.Element == S2.Element, S1.Element : Hashable {

    return false

}

-----------

var stack1 = Stack()

var stack2 = Stack()

// error: requires the types 'Int' and 'String' be equivalent equal(stack1, stack2)

协议类型的注意点

protocol Runnable {}

class Person : Runnable {}

class Car : Runnable {}

func get(_ type: Int) -> Runnable { if type == 0 {

        return Person()

    }

    return Car()

}

var r1 = get(0)

var r2 = get(1)

---------------

如果协议中有associatedtype

protocol Runnable {

    associatedtype Speed

    var speed: Speed { get }

}

class Person : Runnable {

    var speed: Double { 0.0 }

}

class Car : Runnable {

    var speed: Int { 0 }

}

泛型解决

    解决方案1:使用泛型

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)

不透明类型(Opaque Type)

    解决方案2:使用some关键字声明一个不透明类型

    some限制只能返回一种类型

func get(_ type: Int) -> some Runnable { Car() }

var r1 = get(0)

var r2 = get(1)

some

    some除了用在返回值类型上,一般还可以用在属性类型上

protocol Runnable { associatedtype Speed }

class Dog : Runnable { typealias Speed = Double }

class Person {

    var pet: some Runnable {

        return Dog()

} }

可选项的本质

    可选项的本质是enum类型

public enum Optional : ExpressibleByNilLiteral { 

    case none

    case some(Wrapped)

    public init(_ some: Wrapped) }

------------

var age: Int? = .none

age = 10

age = .some(20)

age = nil

-----------

var age: Int? = 10

var age0: Optional = Optional.some(10) var age1: Optional = .some(10)

var age2 = Optional.some(10)

var age3 = Optional(10)

age = nil

age3 = .none

---------

switch age {

case let v?:

    print("some", v)

case nil:

    print("none")

}

switch age {

case let .some(v):

    print("some", v)

case .none:

    print("none")

}

---------

var age: Int? = nil

var age0 = Optional.none 

var age1: Optional = .none

----------

var age_: Int? = 10

var age: Int?? = age_

age = nil

var age0 = Optional.some(Optional.some(10)) age0 = .none

var age1: Optional = .some(.some(10)) age1 = .none

------------

var age: Int?? = 10

var age0: Optional = 10

你可能感兴趣的:(精通Swift(17)- 泛型)