zoukankan      html  css  js  c++  java
  • 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
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
     
     
  • 相关阅读:
    Luogu P4316 绿豆蛙的归宿 题解报告
    Luogu P1850 换教室(NOIP 2016) 题解报告
    Rainbow的信号 题解报告
    $CH5105 Cookies$ 线性$DP+$贪心
    算法竞赛 $0×50$ 动态规划 (+一本通
    $CH5104 I-country$ 线性$DP$
    洛谷$2014$ 选课 背包类树形$DP$
    $SP703 Mobile Service DP$
    $POJ1015 Jury Compromise Dp$/背包
    $POJ1742 Coins$ 多重背包+贪心
  • 原文地址:https://www.cnblogs.com/feng9exe/p/9200748.html
Copyright © 2011-2022 走看看