Passing a swift Class to Generic Function

83 views Asked by At

I am trying to dynamically create a class instance based type using generics, however I am facing some strange behavior. In example 1, everything works, but in Example 2, if i pass Test.self to the generic function, it doesn't work. The type is the same, everything is the same, i don't understand why.

class Test{
  required init(x: Int){
    // Do Something
  }
}

class Builder{
  init(){
  }

  func use<T>(test2: T.Type) -> Void{
    test2(x: 10) // Error: T cannot be constructed because it has no accessible initializers 
  }
}

// Example 1:
let test1 = Test.self
test1(x: 10)

// Example 2:
let builder = Builder()
builder.use(Test.self)
2

There are 2 answers

0
Qbyte On BEST ANSWER

It's because T is not of Type Test. To fix this:

class Builder{
  init(){
  }

  // T has to be of type Test or is a subclass of Test
  func use<T: Test>(test2: T.Type) -> Void{
    test2(x: 10)
  }
}
0
Marcos Crispino On

When you define the use<T> function, you must tell it somehow that the class you are passing will have a init(x:) constructor.

You can do that by declaring a protocol, and making the optional type T conform to that protocol.

Try this:

protocol TestProtocol {
    init(x:Int)
}

class Test: TestProtocol {
    required init(x: Int){
        // Do Something
    }
}

class Builder{
    init(){
    }

    func use<T: TestProtocol>(test2: T.Type) -> TestProtocol {
        return test2(x: 10)
    }
}

PD: tested on Swift 1.2