When I want to check if a type conforms to a simple protocol, I can use:
if let type = ValueType.self as? Codable.Type {}
When the protocol has associated type, for example RawRepresentable
has RawValue
, when I do:
if let type = ValueType.self as? RawRepresentable.Type {}
Compiler will show the following error:
Protocol 'RawRepresentable' can only be used as a generic constraint because it has Self or associated type requirements
So how to check conformance to protocol with associated type?
What is an associated type? An associated type can be seen as a replacement of a specific type within a protocol definition. In other words: it's a placeholder name of a type to use until the protocol is adopted and the exact type is specified. This is best explained by a simple code example.
Protocol Conformance Swift classes, structures, and enumerations can all conform to protocols. The syntax for conforming to a protocol is to add the protocol name after the type name, separated by a colon. A type can declare conformance to multiple protocols by listing the protocol names separated by commas.
Protocols allow you to group similar methods, functions, and properties. Swift lets you specify these interface guarantees on class , struct , and enum types. Only class types can use base classes and inheritance from a protocol.
In Swift, protocols contain multiple abstract members. Classes, structs and enums can conform to multiple protocols and the conformance relationship can be established retroactively. All that enables some designs that aren't easily expressible in Swift using subclassing.
TL;DR
Compiler does not have enough information to compare the type until associated type is set.
When you refer to simple protocol, compiler knows its type from the beginning. But when you refer to protocol with associated type, compiler doesn't know its type until you declare it.
protocol ExampleProtocol {
associatedtype SomeType
func foo(param: SomeType)
}
At this moment for compiler it looks like this:
protocol ExampleProtocol {
func foo(param: <I don't know it, so I'll wait until it's defined>)
}
When you declare a class conforming to the protocol
class A: ExampleProtocol {
typealias SomeType = String
func foo(param: SomeType) {
}
}
Compiler starts to see it like this:
protocol ExampleProtocol {
func foo(param: String)
}
And then it is able to compare types.
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