Make protocols conforming to protocols as only struct/enum/class types can conform to protocols now

Why this is so hard to implement container of protocols in Swift?

My custom container implemented as

let listeners = Listeners<MyListener>()

raises issue:

Value of protocol type 'MyListener' cannot conform to 'ListenerProtocol'; only struct/enum/class types can conform to protocols

It would be nice to make it working for protocols. Full example:

protocol ListenerProtocol: class {}

class Listeners<ListenerType: ListenerProtocol> {

    private class ListenerWeakReference<ListenterType: ListenerProtocol> {
        weak var listener: ListenterType?
        init(listener: ListenterType) {
            self.listener = listener
        }
    }

    private var listeners: [ListenerWeakReference<ListenerType>] = []

    func add(listener: ListenerType) {
        self.listeners.append(ListenerWeakReference<ListenerType>(listener: listener))
    }

    func remove(listener: ListenerType) {
        self.listeners.removeAll { $0.listener === listener }
    }

    func forEach(_ closure: (_ listener: ListenerType) -> Void) {
        for listenerWeakReference in self.listeners where listenerWeakReference.listener != nil {
            closure(listenerWeakReference.listener!)
        }
    }
}

protocol MyListener: ListenerProtocol {
    func didSomethingHappen()
}

let listeners = Listeners<MyListener>() // Value of protocol type 'MyListener' cannot conform to 'ListenerProtocol'; only struct/enum/class types can conform to protocols

Hi! This is something that core team wants to fix, check out "Clarifying existential types" section of Improving the UI of generics

1 Like

What you are facing here is a combination of the two known problems -

So, in the ideal world, generic signature of your class would look like this:

class Listeners<ListenerType> where ListenerType: any ListenerProtocol, ListenerType: Referencable {
...
}
3 Likes