Protocol inheritance with associated type
Once a protocol has an associated type, that protocol can't be used as a type by itself for instance declarations-- only for generic constraints and declaring conformance.
So in this case, Swift is saying "yeah, but what is the concrete type for StartRouterProtocol
's associated type?"
In this case, it's asking you to either:
- Use a concrete type directly, i.e.
let router: MyStartViewClass
with this conformance declaration, elsewhere:class MyStartViewClass: StartRouterProtocol { ... }
) - OR, push the need for a concrete type up one layer, as a generic constraint i.e.
class MyRouterController<T: StartRouterProtocol> {
let router: T
}
This is probably not what you were hoping for, but unfortunately associated types add complexity to how you use protocols, especially if you're familiar with generics & interfaces from other languages. (i.e. Java/C# interfaces)
You can work around some aspects of associated types by using a concept called "type erasure" -- but that can cause other problems and complexity.
Here's some further reading that may help: https://medium.com/monstar-lab-bangladesh-engineering/swift-from-protocol-to-associatedtype-then-type-erasure-a4093f6a2d08
Use protocol that inherits from another protocol as an associated type
Your example is too complicated to understand. I tried to simplify it.
It compiles without errors:
protocol ProtocolA {}
protocol ProtocolB {
associatedtype SomeType
}
class SomeClass: ProtocolB {
typealias SomeType = ProtocolA
}
let object = SomeClass()
But the following example is no longer compiled:
protocol ProtocolA {}
protocol ProtocolB {
associatedtype SomeType: ProtocolA
}
class SomeClass: ProtocolB {
typealias SomeType = ProtocolA
}
The error is as follows:
error: type 'SomeClass' does not conform to protocol 'ProtocolB'
note: possibly intended match 'SomeType' (aka 'ProtocolA') does not conform to 'ProtocolA'
This is because protocols don't conform to themselves
Most likely in your case it is necessary to make the class template:
protocol ProtocolA {}
protocol ProtocolB {
associatedtype SomeType: ProtocolA
}
class SomeClass<T: ProtocolA>: ProtocolB {
typealias SomeType = T
}
extension Int: ProtocolA {}
extension Double: ProtocolA {}
let object1 = SomeClass<Int>()
let object2 = SomeClass<Double>()
Adoption of Protocol in Swift
It's because the protocol X
states that someA
is of type A
, so in class Y
, if you made someA
of type B
, then you couldn't assign anything of type A
to it, which the protocol says that you need to be able to do.
If the protocol said that you needed a variable to hold any Car
, and you had a Porsche
, so you just wanted to tell your protocol conforming class that the variable could only hold a Porsche
, then someone who comes along and tries to put a Mazda
into your Porsche
variable would encounter an issue, since the protocol says they should be able to.
Swift Self as associated type bound in protocol
Are you trying to say this?
protocol Factory {
associatedtype MyType
func new() -> MyType
}
protocol SelfFactory: Factory {
func new() -> Self
}
Protocol composition confusing
T
is not a protocol. T
is a concrete type that conforms to Typeable. You cannot then say that request
must be "of the concrete type T
and also conforms to SocketIORepresentable." What you meant is that T
is a concrete type that conforms to both:
private func sendRequest<T: Typeable & SocketIORepresentable>(_ request: T, completion: @escaping (Result<T.Item, Error>) -> Void) { ... }
Typically you'd write this with a where
clause instead to avoid such a large angle-bracket:
private func sendRequest<T>(_ request: T, completion: @escaping (Result<T.Item, Error>) -> Void)
where T : Typeable & SocketIORepresentable { ... }
Related Topics
How to Override Layout of Nstableheaderview
Why No Infinite Loop in Didset
Given a Hexadecimal String in Swift, Convert to Hex Value
Getting Data from Findobjectsinbackgroundwithblock in Swift
Can't Use Concrete Subclass to Implement a Property in Protocol in Swift
In Swift, What Does This Specific Syntax Mean
Error Handling in Swift Does Not Involve Stack Unwinding. What Does It Mean
Which Swift Character Count Should I Use When Interacting with Nsstring APIs
How to Store a Reference to an Integer in Swift
Why Can't I Pass an Implicitly Unwrapped Optional as an Unsafemutablepointer
Can't Parse JSON Array with JSONdecoder in Swift 4
How to Add External .Vtt Subtitle File to Avplayerviewcontroller in Tvos
Swift 3:Issue with Avvideocompositioncoreanimationtool to Add Watermark on Video
Can You Give Uistackview Borders
Attaching Audiounit Effects to Scnaudiosource Nodes in Scenekit