You can declare Fruit as a protocol that provides the required init method and use generics support in Switchf:
protocol Fruit { init(unknownNumber: Int) } class Apple: Fruit { required init(unknownNumber: Int) { } } class Orange: Fruit { required init(unknownNumber: Int) { } } func makeFruit<T: Fruit>(cls: T.Type) -> Int -> T { return { T(unknownNumber: $0) } } makeFruit(Apple.self)(10)
It also gives you type safety as a result of the makeFruit function, similar to the type specified by the cls parameter.
Note that this is not a factory function, but simply a redirect. But you can go even further and configure makeFruit for some of the fruits, and that is what makes it a factory function:
class Apple: Fruit { required init(unknownNumber: Int) { } init(color: String, unknownNumber: Int) { } } func makeFruit<T: Fruit>(cls: T.Type) -> Int -> T { return { T(unknownNumber: $0) } } func makeFruit(cls: Apple.Type) -> Int -> Apple { return { Apple(color: "red", unknownNumber: $0) } } makeFruit(Orange.self)(15)
Assuming the Apple class has an initializer that accepts color, we can override makeFruit for that particular class and pass the default color (or, possibly, calculated, depending on factory specifications). This is without losing the type of security that grows on you with Swift.
source share