IOS开发Swift笔记17-泛型

泛型

泛型可以将类型参数化,提高代码复用率,减少代码量
泛型函数赋值给变量
————————————————————————————————————

func swapValue<T>(_ a: inout T, _ b: inout T){
    (a, b) = (b, a)
}
var i1 = 10
var i2 = 20
swap(&i1, &i2)

var d1 = 10.0
var d2 = 20.0
swap(&d1, &d2)

struct Date {
    var year = 0, month = 0, day = 0
}
var dd1 = Date(year: 2020, month: 9, day: 10)
var dd2 = Date(year: 2020, month: 10, day: 11)
swap(&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> {}

struct Stack<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 }
}

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

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

————————————————————————————————————

关联类型

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

protocol Stackable {
    associatedtype Element // 关联类型
    mutating func push(_ element: Element)
    mutating func pop() -> Element
    func top() -> Element
    func size() -> Int
}

class Stack<E>: Stackable {
    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 {
    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<T : Person & Runnable>(_ a: inout T, _ b: inout T) {
    (a, b) = (b, a)
}

protocol Stackable {
    associatedtype Element: Equatable
}
class Stack<E : Equatable> : Stackable { typealias Element = E }

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

var stack1 = Stack<Int>()
var stack2 = Stack<String>()
// 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 }
}

在这里插入图片描述
在这里插入图片描述————————————————————————————————————

泛型解决

解决方案①:使用泛型

func get<T : Runnable>(_ 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 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<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 age: Int? = nil
var age0 = Optional<Int>.none
var age1: Optional<Int> = .none

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

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? = 10
var age: Int?? = age_
age = nil

var age0 = Optional.some(Optional.some(10))
age0 = .none
var age1: Optional<Optional> = .some(.some(10))
age1 = .none


var age: Int?? = 10
var age0: Optional<Optional> = 10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SY.ZHOU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值