While designing APIs, I run into this at every corner:
Protocol can only be used as a generic constraint because it has Self or associatedType requirements
What that means is that you basically can not use Self
or associatedtype
on protocol level if you ever plan to use the protocol type on its own -- otherwise the need for types to be generic themselves cascades out of control.
This is rather annoying (read: makes it next to impossible to design reasonable APIs, e.g. such that expose protocols but hide implementations). For instance, you can not have a simple data container protocol:
protocol DataContainer: Equatable {
var id: Int { get }
var content: Data { get }
}
The issue is that Equatable
requires static function ==
which is, of course, expressed using Self
. Therefore, you can not have a type like [DataContainer]
, or any number of other natural things. I first ran into it with groups (arrays) of users (which could be of one of three different types).
The "official" recommended "solution" is to have delegating/wrapper structs that eliminate the type variable, like AnyDataContainer
. This feels like a rather silly, hacky workaround, not proper API design.
I honestly don't get why the type system has this restriction. What are the reason? Why can't the compiler implicitly create AnyP
for every protocol P
to work around it?