简体   繁体   中英

Is there a way to make sealed classes generics?

How a generic result or error type could be defined in Kotlin? Something like this example from TypeScript

type Errorneous<E, R> = 
  { is_error: true, error: E } | { is_error: false, result: R }

function calculate(): Errorneous<String, Number> { 
  return { is_error: false, result: 2 }
}

The problem is that Kotlin doesn't have generic sealed classes.

It's possible to define something like

data class Errorneous<E, R>(val error: E?, val result: R?)

But it not ideal as it allows wrong usage like

Errorneous<String, Int>(null, null)
Errorneous<String, Int>("", 2)

UPDATE

Possible (not compiling) Kotlin code

sealed class Errorneous
class Success<R>(val result: R) : Errorneous()
class Fail<R>(val error: R) : Errorneous()

fun calculate(): Errorneous {
  return Success(2)
}

fun main() {
  val result = calculate()
  if (result is Success<*>) { 
    val r: Int = result.result // <= Problem here, no smart cast
  }
}

You have to add generic parameters to the base class as well:

sealed class Errorneous<E,R>
class Error<E,R>(val error: E): Errorneous<E,R>()
class Success<E,R>(val result: R): Errorneous<E,R>()


fun calculate(): Errorneous<String, Int> {
    return Success(2)
}

fun main() {
    val result = calculate()
    if (result is Success<*, Int>) {
        val r: Int = result.result // <= smart cast
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM