Создать массив протоколов с ограниченными связанными типами - PullRequest
0 голосов
/ 15 декабря 2018

Это базовый пример создания массива протоколов со связанными типами с использованием стирания типов:

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()
    }
}

Создать их массив несложно:

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

IsЕсть ли способ, которым я могу создать массив протоколов, которые имеют связанные типы , которые ограничены ?Вот что я попробовал:

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()
    }
}

Он компилируется!Но разве это не победило шанс создания массива AnyProtocolA сейчас?Теперь я не могу использовать тип Any в качестве заполнителя в моем массиве.

Как мне создать массив AnyProtocolA , который имеет связанный связанный тип?Это вообще возможно?Это не будет работать, поскольку Any ofcourse не соответствует Validateable:

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

Расширение Нельзя сделать:

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

Редактировать: Я думаю, что яуже нашел его, просто введите стирание протокола Validateable, а также:

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 {}

Теперь я могу использовать его как:

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

Любые ответы, которые лучше, всегда приветствуются:)

...