Nullable of nullable in Kotlin?

Viewed 62

I have a use case where I need double level of nullable, something like x: SomeClass??. See prefetchedRecord argument in java code below

public Optional<SomeClass> fetchRecord(Long id) {
   ...
}

public void process(
    Long id,
    Optional<Optional<SomeClass>> prefetchedRecord
) {
  Optional<SomeClass> fetchedRecord = prefetchedResult.orElseGet( () -> fetchRecord(id) )
  if (fetchedRecord.isPresent()) { ... process ... }
  else { ... do something else ... }
}

So for the prefetchedRecord the inner optional signifies the result of the fetching and the outer optional shows whether the fetching was ever done before calling the process function. I use two optional to avoid refetching the record even if the fetching returned nothing.

How would you write this in Kotlin? I realize using double optional is not that clear and I could use a custom class instead, smth like

data class FetchResult<T>(val result: T, val fetched: boolean)

but I wonder if there is something built in into Kotlin to support this use case.

2 Answers

There is no way to do nullable of nullable in Kotlin. I think Kotlin way is avoid null in most cases. You can use sealed-classes for more expressive code.

For example:

sealed class Result<out T> {
    data class Fetched<T>(val result: T): Result<T>()
    data class Prefetched<T>(val result: T): Result<T>()
    object None: Result<Nothing>()
}

Sealed classes provides algebraic data types support and you can make very expressive types with this powerful language feature. You also can use Kotlin standard Result in some cases

No, there is nothing built-in in Kotlin to handle your requirements. If you are targeting Java platform you can use java.util.Optional<T> class:

fun process(id: Long, prefetchedRecord: Optional<Optional<SomeClass>>) {
    ...
}

Or you can try to use java.util.Optional<T> class like this:

fun process(id: Long, prefetchedRecord: Optional<SomeClass>?) {
    ...
}
Related