protocol P {...}
protocol P1: P {...}
protocol P2: P {...}
protocol P3: P {...}
...
Class A<T: P> {
func foo(_ arg: T) {...}
...
}
let a = A<P1>()
Compiler: using P1
as a concrete type conforming to P
is not supported.
Workaround(with the same protocols):
Class A {
func foo(_ arg: P1) {...}
...
}
Class B {
func foo(_ arg: P2) {...}
...
}
Class C {
func foo(_ arg: P3) {...}
...
}
This is, obviously, a classic example of what happens when we can’t use generics.
There are some nuances concerning this. If we use protocols as constrained generic parameters, we have to:
- Somehow indicate that the parameter is protocol-only, or else (in the case of several such parameters) there would be no consideration for interaction of unrelated concrete types, conforming to those protocols, and, therefore, senseless code.
Here is an example of the above mentioned nuance: problem-in-extensions-of-protocols-with-associatedtypes
- Obviously, we also have to restrict inheritance constraints (class type constraints) in such parameters. Fortunately, the Compiler already accounts for this
Maybe adding a specifier to indicate that the parameter is a protocol would be a decent idea:
class Foo<protocol P: Constraint>
EDIT
The need to pass protocols, refining some protocol P
, as generic parameters can be bypassed if the reason for such a need is the ability to pass protocols refining P
with equal by structure requirements yet different concrete types. Expressible via a single protocol with an identical to the latter structure and necessary associatedtype
requirements, in other words.