Cilenco
Cilenco

Reputation: 7179

Method call with nullable and not nullable Collection

Is it possible in Kotlin to write a function which can be called with nullable and not nullable collections? I think about something like this:

fun <C: MutableCollection<out String>> f(c: C): C {
    // ...
}

Not that I need to write it like this because I have a return value of type C. Also note the out keyword but even with it I can't call f(mutableListOf<String?>) but f(mutableListOf<String>) works fine. What do I have to change here or isn't that possible in Kotlin? With arrays this would work just fine...

Upvotes: 0

Views: 84

Answers (2)

Roland
Roland

Reputation: 23352

I think you are mixing things up here (referring to your comment)... Collection<out T> would work the same way as Array<out T>. In that case T could by anything (i.e. T : Any?)... as soon as you set the T to String, which you are basically doing with your C, then you must use a non-nullable type...

While the short answer is to just add ? to the generic type C, i.e. using fun <C: MutableCollection<out String?>> f(c: C):C here are some more examples which may help to better understand how that all plays together:

// your variant:
fun <C : MutableCollection<out String>> f1(c: C): C = TODO()
// given type must be non-nullable; returned one therefore contains too only non-nullable types

// your variant with just another generic type
fun <T : String, C : MutableCollection<out T>> f2(c: C): C = TODO()
// you have now your "out T", but it still accepts only non-nullable types (now it is probably just more visible as it is in front)

// previous variant adapted to allow nullable types:
fun <T : String?, C : MutableCollection<out T>> f3(c: C): C = TODO()

Finally the solution to your problem can be one of the following (depending what you really require):

fun <T : String?> f4a(c: MutableCollection<out T>): MutableCollection<out T> = TODO()
fun <C : MutableCollection<out String?>> f4b(c: C): C = TODO()

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 692231

fun <C: MutableCollection<out String?>> f(c: C): C {
    return c;
}

fun main(args: Array<String>) {
    println(f(mutableListOf("hello")))
    println(f(mutableListOf<String?>(null)))
}

Upvotes: 2

Related Questions