I have the following protocol and its extension
public protocol RESEndpointReachable: CustomDebugStringConvertible
{
associatedtype EndpointType: RESEndpointReachable
// MARK: - Properties
/// The name of the endpoint as defined in the REST URI.
var name: String { get }
/// An array of possible next endpoints that this endpoint can reach. E.g account's next endpoints would be authenticate and unauthenticate.
var nextPossibleEndpoints: [EndpointType] { get }
// MARK: - Ability
/// Used to process the endpoint.
func processRequest(request: RERequest)
/// Processes the next endpoint that matches the name `name`. Expects an endpoint with the name `name` to exist in `nextPossibleEndpoints`.
func processNextEndpointWithName(name: String, request: RERequest)
}
public extension RESEndpointReachable
{
// MARK: - CustomDebugStringConvertible
public var debugDescription: String {
return name
}
// MARK: - RESEndpointReachable
var nextPossibleEndpoints: [EndpointType] {
return []
}
public func processRequest(request: RERequest)
{
// Check all possible endpoints are being processed
if let nextEndpoint = nextPossibleEndpoints.first
{
fatalError("Unhandled endpoint \(nextEndpoint).")
}
}
public func processNextEndpointWithName(name: String, request: RERequest)
{
// Get the next endpoint that matches the specified name
let nextEndpoints = nextPossibleEndpoints.filter { $0.name == name }
if nextEndpoints.count > 1
{
fatalError("Multiple next endpoints found with the name '\(name)'.")
}
guard let nextEndpoint = nextEndpoints.first else
{
fatalError("No next endpoint with the name '\(name)'.")
}
// Process the next endpoint
nextEndpoint.processRequest(request)
}
}
On building, the line associatedtype EndpointType: RESEndpointReachable
has the following error: Type may not reference itself as a requirement
. But as I understand it this is how you use associated types in Swift.
As you may have guessed, I always want whatever EndpointType
ends up being set as to be a type that inherits from RESEndpointReachable
.
This feature is referred to by the Swift team as 'recursive protocol constraints', and is on the roadmap to be added in a future version of Swift. For more information about this and other planned features, check out the Swift team's 'Completing Generics' manifesto.
Yep, that is not OK with swift. A protocol can't use it self as a type constraint. One solution is to declare an extra protocol that RESEndpointReachable itself will adopt and constraint RESEndpointReachable to that super protocol.
I took the example from the book iOS 10 Programming Fundamentals with Swift by Neuburg M. (please see page 194)
illegal example:
1 protocol Flier {
2 associatedtype Other : Flier
3 func flockTogetherWith(_ f: Other)
4 }
5
6 struct Bird : Flier {
7 func flockTogetherWith(_ f: Bird) {}
8 }
Solution:
1 protocol Superflier {}
2 protocol Flier: Superflier {
3 associatedtype Other : Superflier
4 func flockTogetherWith(_ f: Other)
5 }
6
7 struct Bird : Flier {
8 func flockTogetherWith(_ f: Bird) {}
9 }
Cheers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With