Your IdentifierProtocol
is RawRepresentable
, which has associatedType
. And such protocol cannot be used "like if it was concrete type".
That is basically what the compilation error says:
error: protocol 'A_IdentifierProtocol' can only be used as a generic constraint because it has Self or associated type requirements
Instead of duplicating information, I suggest you reading this explanation of the error you are getting: https://stackoverflow.com/a/36350283/2378431
If you want to workaround this error and still have your code working without any obvious difference (from usage perspective), you could define single method for each X_IdentifierProtocol
, something like this:
protocol IdentifierProtocol: Equatable, RawRepresentable {}
protocol A_IdentifierProtocol: IdentifierProtocol {}
protocol B_IdentifierProtocol: IdentifierProtocol {}
func myFunc<I: A_IdentifierProtocol>(identifier: I) where I.RawValue == String {
print("A: \(identifier.rawValue)")
}
func myFunc<I: B_IdentifierProtocol>(identifier: I) where I.RawValue == String {
print("B: \(identifier.rawValue)")
}
The disadvantage is that for every X_IdentifierProtocol
you need to provide one method implementation and could introduce some code duplication if you'd like to have piece of shared code based on IdentifierProtocol
.
Another approach: If you really want single function, you cannot have IdentifierProtocol
with associated type. However you can have multiple type constraints on generic function, something like this:
protocol IdentifierProtocol {}
protocol A_IdentifierProtocol: IdentifierProtocol {}
protocol B_IdentifierProtocol: IdentifierProtocol {}
func myFunc<I: IdentifierProtocol & Equatable & RawRepresentable>(identifier: I) where I.RawValue == String {
if identifier is A_IdentifierProtocol {
print("A: \(identifier.rawValue)")
}
if identifier is B_IdentifierProtocol {
print("A: \(identifier.rawValue)")
}
}
class MyClassA: A_IdentifierProtocol, RawRepresentable, Equatable {...}
class MyClassB: B_IdentifierProtocol, RawRepresentable, Equatable {...}
But not even this is perfect and does not full cover your requirements.
Bottomline is that you cannot achieve exactly what you want with Swift 3.