absoftware
(Ariel Bogdziewicz)
1
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
cukr
2
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