0

How I can create a protocol variable. My goal is a protocol will be have a function with a generic type and I'm using associatedtype which is accessing to Class and the function will be return generic type. Example declaration below:

public protocol ComponentFactory {
   associatedtype T // A class and that class can be inherit from another so I need define generic type here
   func create() -> T
}

I want to declare a variable for this protocol like that:

fileprivate var mComponentFactoryMap = Dictionary<String, ComponentFactory>()

At this line I receive a error: Protocol 'ComponentFactory' can only be used as a generic constraint because it has Self or associated type requirements

I see from Android, actually from kotlin they have a declare for interface like:

private val mComponentFactoryMap = mutableMapOf<String, ComponentFactory<*>>()

Any guys can help me, how I can declare this from Swift?

Huy Nguyen
  • 77
  • 1
  • 12
  • Check this link: https://stackoverflow.com/questions/39338692/why-do-i-get-the-error-protocol-can-only-be-used-as-a-generic-constraint-beca – 3stud1ant3 Oct 06 '17 at 01:56
  • Swift needs to know what the type of `T` will be in `mComponentFactoryMap`. Without knowing what type it is, the compiler can't do the required type checking. – Gary Makin Oct 06 '17 at 02:14
  • @GaryMakin I've comment on that line `associatedtype`. Do that like `associatedtype T: Component // Component is a class` – Huy Nguyen Oct 06 '17 at 02:37
  • @3stud1ant3 Sorry but from that link I just know about pure Type I don't figure out how to defined like what my question? Can you explain more? – Huy Nguyen Oct 06 '17 at 02:39

1 Answers1

2

I've solved this from few months ago with descriptions below. Please check it and give me another solution if you have.

Firstly, make some change for Protocol. At associatedtype T should be change to associatedtype Component and Component is a class which will be inherited from another class (important step).

public protocol ProComponentFactory {
    associatedtype Component
    func create() -> Component?
} 

Second, I will make a Generic Struct with inheritance from ProComponentFactory:

public struct ComponentFactory<T>: ProComponentFactory {
    public typealias Component = T
    public func create() -> T? { return T.self as? T }
}

Well done, for now you can define a variable as I example in my question above:

fileprivate var mComponentFactoryMap = Dictionary<String, ComponentFactory<Component>>()

As well for any class was inherit from Component and variable mComponentFactoryMap can using extension inside.

Huy Nguyen
  • 77
  • 1
  • 12