2016-09-17 58 views
0

我想在Swift 3中使用閉包創建一個類型擦除類型,但我不知道如何將閉包存儲在屬性中。我如何存儲閉包供以後使用?請參見下面的代碼:如何存儲通用閉包?

protocol ProtocolA { 
    associatedtype AssociatedType 
} 

protocol ProtocolB { 
    associatedtype AssociatedType 
    func fn<A: ProtocolA>(a: A) where A.AssociatedType == AssociatedType 
} 

class AnyProtocolB<T>: ProtocolB { 
    typealias AssociatedType = T 

    init<A: ProtocolA>(fn: @escaping (A) -> Void) where A.AssociatedType == AssociatedType { 
     _fn = fn 
    } 

    func fn<A: ProtocolA>(a: A) where A.AssociatedType == AssociatedType { 
     _fn(a) 
    } 

    let _fn: (A) -> Void // how to declare this so it will compile? 
} 

作爲一個方面說明,我能夠通過聲明它這樣做這在斯威夫特2:

let _fn: (AnyProtocolA<AssociatedType>) -> Void 

但上面並沒有在斯威夫特3工作(它崩潰的編譯器)

回答

0

它看起來像這樣工作的:

protocol ProtocolA { 
    associatedtype AssociatedType 
} 

class AnyProtocolA<T>: ProtocolA { 
    typealias AssociatedType = T 

    init<A: ProtocolA>(_ a: A) where AssociatedType == A.AssociatedType { 

    } 
} 

protocol ProtocolB { 
    associatedtype AssociatedType 
    func fn<A: ProtocolA>(a: A) where A.AssociatedType == AssociatedType 
} 

class AnyProtocolB<T>: ProtocolB { 
    typealias AssociatedType = T 

    init<A: ProtocolA>(fn: @escaping (A) -> Void) where A.AssociatedType == AssociatedType { 
     _fn = { fn(wrap($0)) } 
    } 

    func fn<A: ProtocolA>(a: A) where A.AssociatedType == AssociatedType { 
     _fn(AnyProtocolA(a)) 
    } 

    let _fn: (AnyProtocolA<T>) -> Void 
} 

func wrap<A: ProtocolA, T>(_ a: AnyProtocolA<T>) -> A where A.AssociatedType == T { 
    return a as! A 
}