0

I have a generic function where I am passing protocol type and based on the passed type I am returning a required struct. If I put a protocol constraint on the generic even if the passed protocol conforms to it I am getting an error.

protocol BaseProtocol {}

protocol ProtocolA: BaseProtocol {}
protocol ProtocolB: BaseProtocol {}

struct StructA: ProtocolA {}
struct StructB: ProtocolB {}

When I define my function with a constraint like this:

func getStruct<T: BaseProtocol>(type: T.Type) -> T {
   switch type {
   case is ProtocolA.Protocol:
       return StructA() as! T
   case is ProtocolB.Protocol:
       return StructB() as! T
   default:
       fatalError("Unknown Type")
   }
}

let result = getStruct(type: ProtocolA.self)
print(type(of: result))

It does not work and generates the following error:

xcode error

If I remove the BaseProtocol constraint all works fine:

func getStruct<T: Any>(type: T.Type) -> T {
   switch type {
   case is ProtocolA.Protocol:
       return StructA() as! T
   case is ProtocolB.Protocol:
       return StructB() as! T
   default:
       fatalError("Unknown Type")
   }
}

Is there any other way to put that constraint? Am I doing something wrong here?

Guferos
  • 4,337
  • 5
  • 18
  • 25
  • 1
    That's because in Swift protocols don't conform to parent protocols – Cristik Sep 21 '18 at 14:41
  • 1
    More info about the above, here: https://stackoverflow.com/a/43408193/1974224 – Cristik Sep 21 '18 at 14:43
  • not an answer to your question but have you thought about creating an extension to your protocol that implements that method in combination with the type(of:)? – dniswhite Sep 21 '18 at 15:05

1 Answers1

0

In fact, you don't get a protocol type in your getStruct method's type parameter. You get a struct, enum or class that conform BaseProtocol

You can look this for more information: Answer of: Why can't I pass a Protocol.Type to a generic T.Type parameter?

Ekrem Duvarbasi
  • 189
  • 1
  • 7