1. 程式人生 > >swift中的"類型擦除"

swift中的"類型擦除"

兩個 constrain conf 簡化 sed c const auth associate code

在 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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並註明出處。

swift中的"類型擦除"