Create an array of protocols with constrained associated types

☆樱花仙子☆ 提交于 2020-01-04 00:13:42

问题


This is a basic example of creating an array of protocols with associated types using type erasure:

protocol ProtocolA {
    associatedtype T

    func doSomething() -> T
}

struct AnyProtocolA<T>: ProtocolA {
    private let _doSomething: (() -> T)

    init<U: ProtocolA>(someProtocolA: U) where U.T == T {
        _doSomething = someProtocolA.doSomething
    }

    func doSomething() -> T {
        return _doSomething()
    }
}

Creating an array of them isn't hard:

let x: [AnyProtocolA<Any>] = []

Is there any way way I can create an array of protocols which have associated types that are constrained? This is what I have tried:

protocol Validateable {
    // I removed the functions and properties here to omit unreleveant code.
}

protocol ProtocolA {
    associatedtype T: Validateable

    func doSomething() -> T
}

struct AnyProtocolA<T: Validateable>: ProtocolA {
    private let _doSomething: (() -> T)

    init<U: ProtocolA>(someProtocolA: U) where U.T == T {
        _doSomething = someProtocolA.doSomething
    }

    func doSomething() -> T {
        return _doSomething()
    }
}

It compiles! But didn't it defeated the chance of creating an array of AnyProtocolA's now? Now I can't use type Any as a placeholder in my array.

How do I create an array of AnyProtocolA's which has a constrained associated type? Is it even possible? This won't work since Any ofcourse doesn't conform to Validateable:

let x: [AnyProtocolA<Any>] = []

Extending Any can't be done:

extension Any: Validateable {} // Non nominal type error

Edit: I think I already found it, just type erasure the protocol Validateable as well:

protocol Validateable {
    // I removed the functions and properties here to omit unreleveant code.
}

protocol ProtocolA {
    associatedtype T: Validateable

    func doSomething() -> T
}

struct AnyProtocolA<T: Validateable>: ProtocolA {
    private let _doSomething: (() -> T)

    init<U: ProtocolA>(someProtocolA: U) where U.T == T {
        _doSomething = someProtocolA.doSomething
    }

    func doSomething() -> T {
        return _doSomething()
    }
}

struct AnyValidateable<T>: Validateable {}

Now I can use it as:

let x: [AnyProtocolA<AnyValidateable<Any>>] = []

Any answers that are better are always welcome :)

来源:https://stackoverflow.com/questions/53796227/create-an-array-of-protocols-with-constrained-associated-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!