How to write generic factory method in swift?

I am not sure how to, if it’s possible to, write method that calls constructor of it’s generic type inheriting from common known base class < T:Base > to create some instances of T without resorting to explicit factory function i.e. with all bells and whistles provided by type inference.

Example that works in playground:

  • Extending Collection with a recursive property/method that depends on the element type
  • Are generics specialized during compilation or they are just like java generics only for compile time checks?
  • Extending typed array by conforming to a protocol in Swift 2
  • Check if an array contains all elements of another in Swift
  • wrong generic type in swift
  • Apple Swift: Type Casting Generics
  • // Let there be classes MyPod and Boomstick with common Base (not important)
    class Base : Printable {
        let value : String; init(_ value : String) { self.value = "Base." + value }
        var description: String { return value }
    }
    class MyPod : Base {
        init(_ value: String) { super.init("MyPod." + value) }
    }
    class Boomstick : Base {
        init(_ value: String) { super.init("Boomstick." + value) }
    }
    // PROBLEM: do not know how to force call of Boomstick(n) instead of Base(n) in here
    func createSome<T : Base>() -> T[] {
        var result = Array<T>()
        for n in 1...5 {
            result += T(toString(n))
        }
        return result
    }
    // This seems to be fine. 
    // I was expecting call of createSome<Boomstick>() { ... result += Boomstick(n) ...
    let objs : Boomstick[] = createSome() 
    // Prints: Base.1, Base.2, ... not much wished Boomstick.1, Boomstick.2, ...
    println(objs)
    

    One obvious solution is to delegate creation to caller, but that seems clunky:

    func createSome<T>(factory : (Int)->T) { ... }
    

    Thank you.

    PS: Isn’t assignment of createSome()->Base[] to objs:Boomstick[] type safety violation?

    Solutions Collect From Internet About “How to write generic factory method in swift?”

    Right now I don’t have an answer about the why, but defining a protocol with the initializer only seems to work:

    protocol A {
        init(_ value: String)
    }
    

    You implement this protocol in all classes as below

    class Base : Printable, A {
        let value : String;
        init(_ value : String) { self.value = "Base." + value }
        var description: String { return value }
    }
    
    class MyPod : Base, A {
        init(_ value: String) { super.init("MyPod." + value) }
    }
    
    class Boomstick : Base, A {
        init(_ value: String) { super.init("Boomstick." + value) }
    }
    

    and use A rather than Base in your createSome() func

    func createSome<T : A>() -> [T] {
        var result = Array<T>()
        for n in 1...5 {
            result += T(toString(n))
        }
        return result
    }
    

    Tested in playground:

    let objs : [Boomstick] = createSome()
    objs[0]
    

    and it prints:

    {value "Base.Boomstick.1"}
    

    Also tried using MyPod and Base and it printed the expected results.
    Test it out and let me know if it works for you as well.