15-泛型

2020-10-27  本文已影响0人  bytebytebyte
//泛型1-9
//1.泛型:泛型可以将类型参数化,提高代码复用率,减少代码量
func swapValues<T>(_ 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: 2020, month: 9, day: 22)
var dd2 = Date(year: 2020, month: 9, day: 23)
swapValues(&dd1, &dd2)
//泛型函数赋值给变量
func test<T1, T2>(_ t1: T1, _ t2: T2){}
var fn: (Int, Double) -> () = test

class Stack<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 SubStack<E> : Stack<E> {}
var stack = Stack<Int>()
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

struct Stack0<E> {
    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 }
}
enum Score<T> {
    case point(T)
    case grade(String)
}
let score0 = Score<Int>.point(100)
let score1 = Score.point(99)
let score2 = Score.point(99.5)
let score3 = Score<Int>.grade("A")

//2.关联泛型
//关联泛型的作用:给协议中用到的类型定义一个占位名称,协议中可以拥有多个关联类型
protocol Stackable {
    associatedtype Element //关联泛型
    mutating func push(_ element: Element)
    mutating func pop() -> Element
    func top() -> Element
    func size() -> Int
}
class Stack1<E>: 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")
print(ss.top()) //Rose

//4.类型约束
protocol Runnable {}
class Person {}
func swapValues<T: Person & Runnable>(_ a: inout T, _ b: inout T) {
    (a, b) = (b, a)
}
protocol Stackable2 {
    associatedtype Element: Equatable
}
class Stack2<E: Equatable> : Stackable2 { typealias Element = E } 
func equal<S1: Stackable2, S2: Stackable2>(_ s1: S1, _ s2: S2) -> Bool where S1.Element == S2.Element, S1.Element : Hashable {
    return false
}
var s1 = Stack2<Int>()
var s2 = Stack2<Int>()
var s3 = Stack2<String>()
equal(s1, s2)
//equal(s2, s3)

//5.协议类型的注意点
protocol Run {}
class Per : Run {}
class Car : Run {}
func get(_ type: Int) -> Run {
    if type == 0 {
        return Per()
    }
    return Car()
}
var r1 = get(0)
var r2 = get(1)

//6.如果协议中有associatedtype
protocol Walk {
    associatedtype Speed
    var speed: Speed { get }
}
class Pers : Walk {
    var speed: Double { 0.0 }
}
class Bus : Walk {
    var speed: Int { 0 }
}

//7.协议作为返回值类型:泛型解决
func get<T: Run>(_ type: Int) -> T {
    if type == 0 {
        return Per() as! T
    }
    return Car() as! T
}
var c1: Per = get(0)
var c2: Car = get(1)

//8.协议作为返回值类型:不透明类型:使用some关键字声明一个不透明类型
func gets(_ type: Int) -> some Run { Car() }
var e1 = gets(0)
var e2 = gets(1)
//some限制只能返回一种类型
//func get(_ type: Int) -> some Run {
//    if type == 0 {
//        return Per()
//    }
//    return Car()
//}
//Function declares an opaque return type, but the return statements in its body do not have matching underlying types
//some 限制除了用在返回值类型上,一般还可以用在属性类型上
protocol Running { associatedtype Speed }
class Dog : Running { typealias Speed = Double }
class Perso {
    var pet: some Running {
        return Dog()
    }
}
//9.可选项的本质
//可选项的本质是enum类型
//public enum Optional<Wrapped> : ExpressibleByNilLiteral {
//    case none
//    case some(wrapped)
//    public init(_ some: Wrapped)
//}

var age: Int? = 10
var age0: Optional<Int> = Optional<Int>.some(10)

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

var age3 = Optional(10)
age = nil
age3 = .none

var age4: Int? = nil
var age5 = Optional<Int>.none
var age6: Optional<Int> = .none

var ages: Int? = .none
ages = 10
ages = .some(20)
ages = nil

//3个等价
switch ages {
case let v?:
    print("some",v)
case nil:
    print("none")
}

switch ages {
case let .some(v):
    print("some", v)
case .none:
    print("none")
}

if let v = ages {
    print("1", v)
} else {
    print("2")
}

var line_:Int? = 10
var line: Int?? = line_
line_ = nil

var line0 = Optional.some(Optional.some(10))
line0 = .none
var line1: Optional<Optional> = .some(.some(10))
line1 = .none

var line2: Int?? = 10
var line3: Optional<Optional> = 10
上一篇 下一篇

猜你喜欢

热点阅读