Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between T and T? in Kotlin?

Tags:

kotlin

What's the difference between:

fun <T, R> List<T>.map1(transform: (T) -> R): List<R> {
    return this.map(transform)
}

and

fun <T, R> List<T>.map2(transform: (T?) -> R): List<R> {
    return this.map(transform)
}

and

fun <T, R> List<T?>.map3(transform: (T?) -> R): List<R> {
    return this.map(transform)
}

In my test, null is accepted for all 3 transform functions above, so: Is there any difference between T and T??

like image 651
FredSuvn Avatar asked Sep 05 '20 15:09

FredSuvn


People also ask

What does t mean in Kotlin?

T. () -> Unit is an extension function type with receiver. Besides ordinary functions, Kotlin supports extension functions. Such function differs from an ordinary one in that it has a receiver type specification. Here it's a generic T.

What is the difference between * and any in Kotlin generics?

When we define a collection with "*", it should contain the object of only that type. There should not be any mix and match between the data types inside a collection. If we use "Any", we can mix and match the data types, which means we can have multiple data types in a collection.

What is it keyword in Kotlin?

Using “it” keyword in place of a single parameter in Lambdas expressions. Learn about Lambdas Expressions and High-Level Functions. Kotlin as an Android Programming Language. Kotlin supports Functional programming where you can pass a function as a parameter and even return a function. Smartherd.

How do I use this keyword in Kotlin?

In Kotlin, the “this” keyword allows us to refer to the instance of a class whose function we happen to be running. Additionally, there are other ways in which “this” expressions come in handy.


1 Answers

In your examples, T and T? are equivalent, but there are other cases where the ? does make a difference.

When you declare a type parameter <T>, it doesn't have any restrictions on it. It's the same as writing <T: Any?>, and it means T will allow any sub-type of Any?. Adding a ? to it would make it nullable, but Any? is already nullable, so the ? doesn't change anything. That means that the set of types allowed by an unbounded type T is the same as the set of types allowed by T?.

As soon as you put restrictions on what T can be, things change, though. For example, in the following function, we declare a type parameter <T: Any>, restricting it so it's no longer nullable.

fun <T: Any> myFunction(item: T) // item can't be null

That means I can't pass null to myFunction. I can only call the function with a null argument if I change the type of the parameter to be T?.

fun <T: Any> myFunction(item: T?) // item can be null

Note that the ? just annotates an existing type parameter. Declaring a type parameter with a ? doesn't mean anything and doesn't compile. For example, fun <T?> myFunction(item: T) isn't valid Kotlin code.

like image 81
Sam Avatar answered Nov 02 '22 12:11

Sam