swift基础_泛型(T)

2023-02-26  本文已影响0人  李永开

一. 泛型的使用

func swapValue(_ a: inout Int, _ b: inout Int) {
    (a, b) = (b, a)
}
var a = 1
var b = 2
swapValue(&a, &b)
print("\(a), \(b)") //2, 1

//使用泛型<T>
func swapAllValue<T>(_ a: inout T, _ b: inout T) {
    (a, b) = (b, a)
}
var aa = "10"
var bb = "20"
swapAllValue(&aa, &bb)
print("\(aa), \(bb)")   //20, 10

//继承
class Swapclass<T> {
}
class SubClass<T> : Swapclass<T> {
}

二. 泛型的原理

2.1 看SIL

可以看到调用swapAllValue是这样调用的:

//使用泛型<T>
func swapAllValue<T>(_ a: inout T, _ b: inout T) {
    (a, b) = (b, a)
}

var a = 10
var b = 11
swapAllValue(&a, &b)

var aa = "66666666666666666"
var bb = "77777777777777777"
swapAllValue(&aa, &bb)

//swapAllValue 函数, 也就是`s4main12swapAllValueyyxz_xztlF`
// swapAllValue<A>(_:_:)
sil hidden @$s4main12swapAllValueyyxz_xztlF : $@convention(thin) <T> (@inout T, @inout T) -> () {
} // end sil function '$s4main12swapAllValueyyxz_xztlF'

//Int值交换 -> apply %14<Int>(%12, %13)
  // function_ref swapAllValue<A>(_:_:)
  %14 = function_ref @$s4main12swapAllValueyyxz_xztlF : $@convention(thin) <τ_0_0> (@inout τ_0_0, @inout τ_0_0) -> () // user: %15
  %15 = apply %14<Int>(%12, %13) : $@convention(thin) <τ_0_0> (@inout τ_0_0, @inout τ_0_0) -> ()

//string值交换 ->  apply %38<String>(%36, %37) 
  // function_ref swapAllValue<A>(_:_:)
  %38 = function_ref @$s4main12swapAllValueyyxz_xztlF : $@convention(thin) <τ_0_0> (@inout τ_0_0, @inout τ_0_0) -> () // user: %39
  %39 = apply %38<String>(%36, %37) : $@convention(thin) <τ_0_0> (@inout τ_0_0, @inout τ_0_0) -> ()

2.2 看汇编

//  swapAllValue(&a, &b)     bl    0x102904418
//  swapAllValue(&aa, &bb)   bl    0x102904418

2.3 总结

三. associatedtype

protocol Stackable {
    associatedtype Element  //关联类型
    mutating func push(_ element: Element)//mutating是为了Struct也能使用
    func size() -> Int
}
class demoClass : Stackable {
    typealias Element = String//声明Element是String类型,可以省略
    func push(_ element: String) {
        
    }
    func size() -> Int {
        return 100
    }
}

四.类型约束

//类可以有类型约束 -> 泛型必须继承自demoClass
class yueshuclass<T : demoClass> {
    
}

//协议也可以有类型约束 -> Element需要继承自demoClass
protocol StackablePro {
    associatedtype Element : demoClass
    mutating func push(_ element: Element)
    func size() -> Int
}

// 函数的类型约束
func equal<S1: Stackable, S2: Stackable>(_ s1: S1, _ s2: S2) -> Bool where S1.Element == S2.Element, S1.Element : Hashable {
    return false
}

五. 不透明类型 (OpaqueType)

protocol Stackable {
    associatedtype Element  //关联类型
    mutating func push(_ element: Element)//mutating是为了Struct也能使用
    func size() -> Int
}
class demoClass : Stackable {
    typealias Element = String//声明Element是String类型,可以省略
    func push(_ element: String) {
        
    }
    func size() -> Int {
        return 100
    }
}
func opaqueType(_ type: Int) ->  some Stackable {
    return demoClass()
}
// any是干嘛的...不知道...
func opaqueType1(_ type: Int) ->  any Stackable {
    return demoClass()
}
上一篇 下一篇

猜你喜欢

热点阅读