4

Inspired by Create generic 2D array in Kotlin, I have the following code that creates a generic class with an array of type T. However, once I add an upper bound, I get a compile error. Is there a way to do this?

//This code compiles:
class GenericClass<T> protected constructor(size : Int, arrayFactory: (Int) -> Array<T>) {
  companion object {
    inline fun <reified T> invoke(size : Int)
       = GenericClass(size, { size -> arrayOfNulls<T>(size) })
  }
  val array = arrayFactory(size)
}

//Compile errors:
class GenericClass<T : Comparator<T>> protected constructor(size : Int, arrayFactory: (Int) -> Array<T>) {
  companion object {
    inline fun <reified T : Comparator<T>> invoke(size : Int)
       = GenericClass(size, { size -> arrayOfNulls<T>(size) })
  }
  val array = arrayFactory(max)
}

The compile errors are:

  • Type parameter bound for T in constructor GenericClass>(size: Int, arrayFactory: (Int) -> Array) is not satisfied: inferred type T? is not a subtype of Comparator
Community
  • 1
  • 1
U Avalos
  • 6,538
  • 7
  • 48
  • 81

1 Answers1

4

The error message while misleading does hint that it's about nullability constraints of your type arguments and parameters. Change the GenericClass constructor to allow for null inside Array like so:

class GenericClass<T : Comparator<T>> 
  protected constructor(size : Int, arrayFactory: (Int) -> Array<T?>) {
    companion object {
        inline fun <reified T : Comparator<T>> invoke(size : Int)
            = GenericClass(size, { size -> arrayOfNulls<T>(size) })
    }
    val array = arrayFactory(size)
}

arrayOfNulls as the name suggest creates array of given size filled with nulls. Hence if you wish to use it the arrayFactory needs to accept it.

miensol
  • 39,733
  • 7
  • 116
  • 112