如何存储通用闭包?

时间:2016-09-17 14:33:12

标签: swift

我正在尝试使用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?
}

作为旁注,我能够在Swift 2中通过声明这样做:

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

但是上面的内容在Swift 3中不起作用(它会使编译器崩溃。)

1 个答案:

答案 0 :(得分: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
}