Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constrain Kotlin generic to not null in one case

I have a generic type (T: Any?) that I need constrained in one situation never to be null:

class Repository<T> { // T may be a non-null or nullable type.
  fun getFromFoo(): T {}
  fun getFromBar(): T {} // This is never null. Can I mark it as so?
}


val repository = Repository<String>()
val fromFoo: String = repository.getFromFoo() // Returns a non-null String.
val fromBar: String = repository.getFromBar() // How do I make this work?


val repository = Repository<String?>()
val fromFoo: String? = repository.getFromFoo() // Returns a nullable String.
val fromBar: String = repository.getFromBar() // How do I make this return a non-null String?

While I would ideally refactor these into separate types (like FooRepository and BarRepository), is there any way to get this type constraint functionality?

like image 317
Eric Cochran Avatar asked Jan 12 '18 23:01

Eric Cochran


People also ask

What is a type constraint in Kotlin?

A type constraint in general is an inequation of the following form: T <: U T <: U T <: U where T T T and U U U are concrete Kotlin types. As Kotlin has parameterized types, T T T and U U U may be free type variables: unknown types which may be substituted by any other type in Kotlin.

What is non null in Kotlin?

Not-Null Assertion Each type in Kotlin has one nullable form and another non-nullable form. For instance, the Int type can hold non-null 32-bit integers. In addition to the same values, the Int? type can hold null values, too. Kotlin provides many options to facilitate working with nullable data types in a safe manner.

What are generics in Kotlin?

Kotlin generics. Generics are the powerful features that allow us to define classes, methods and properties which are accessible using different data types while keeping a check of the compile-time type safety. A generic type is a class or method that is parameterized over types. We always use angle brackets () to specify the type parameter in ...

How to make a generic class accept non-null type arguments in Kotlin?

Any is the supertype of all non-null types in Kotlin. So, to make a generic class accept only non-null type arguments, you need to explicitly specify Any as an upper bound of T, that is T : Any. This results in the T being non-null in the following example:


1 Answers

What you need is the type T & Any — an intersection of generic T and Any. It represents such subtype of T that can never contain nulls.

Unfortunately the intersection types and this intersection in particular currently are non-denotable in Kotlin, meaning that you can't declare a return type of a function to be non-nullable subtype of T.

like image 89
Ilya Avatar answered Oct 16 '22 13:10

Ilya