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
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
     
     
  • 相关阅读:
    jquery及相关兼容插件的版本搭配
    jquery IE7 下报错:SCRIPT257: 由于出现错误 80020101 而导致此项操作无法完成
    兼顾php和jquery新版本的checkbox的写法
    jquery.validate动态更改校验规则 【转】
    Google的10大座右铭
    用jQuery屏蔽掉按回车键时提交表单
    sizeof()和strlen()在求字符串长度时的差别
    Matlab使用心得
    C++ 数据类型及相关问题 及输出精度控制
    原生javascript满屏上下滚动
  • 原文地址:https://www.cnblogs.com/feng9exe/p/9200748.html
Copyright © 2011-2022 走看看