swift中的"类型擦除"

在 Swift 的世界中,如果我们将协议称之为国王,那么泛型则可以视作皇后,所谓一山不容二虎,当我们把这两者结合起来使用的时候,似乎会遇到极大的困难。那么是否有一种方法,能够将这两个概念结合在一起,以便让它们成为我们前进道路上的垫脚石,而不是碍手碍脚的呢?答案是有的,这里我们将会使用到类型擦除 (Type Erasure) 这个强大的特性。

Protocol 'SpellDelegate' can only be used as a generic constraint because it has Self or associated type requirements

因为swift泛型还不支持逆变和协变也就不会有真的类型擦除,而这里说的"类型擦除"是指:利用一个具体实现的通用泛型类(参看系统库的AnySequence),去包装具体实现了该泛型协议的类。用以解决不能直接使用泛型协议进行变量定义的问题。具体可以看这篇文章

那个ppt的代码看着不方便,我就简化了一下:

protocol Erasable {
    associatedtype DataType
    
    func foo(arg: DataType) -> DataType
}

class AnyErasable<EraseType>: Erasable {
    private var fooFunc: (EraseType) -> EraseType
    
    init<Inject: Erasable>(_ obj: Inject) where Inject.DataType == EraseType {
        fooFunc = obj.foo
    }
    
    func foo(arg: EraseType) -> EraseType {
        return fooFunc(arg)
    }
}

class MyEraseClass: Erasable {
    func foo(arg: Int) -> Int {
        return arg * 10 } } class MyEraseDelegate<T> { var val: T // var delegate: Erasable -- 编译失败 var delegate: AnyErasable<T>? init(_ val: T) { self.val = val } func doSomething() -> T { return (delegate?.foo(arg: val))! } } let test = MyEraseDelegate(35) test.delegate = AnyErasable(MyEraseClass()) print("result: \(test.doSomething())") // 350
 


作者:fuadam1982
链接:https://www.jianshu.com/p/a852865f94fc
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
 
 

猜你喜欢

转载自www.cnblogs.com/feng9exe/p/9200748.html
今日推荐