Lower bound типов или его эмуляция
Предположим, что делается реализация аналога Option/Some/None из Scala. Упрощенная база делается прямолинейно:
sealed class Option<out A> {
abstract fun isDefined(): Boolean
abstract fun get(): A
}
class Some<A>(val value: A) : Option<A>() {
override fun isDefined(): Boolean = true
override fun get(): A = value
}
object None : Option<Nothing>() {
override fun isDefined(): Boolean = false
override fun get(): Nothing = throw NoSuchElementException()
}
Но как добавить getOrElse? Варианты:
abstract fun getOrElse(elseBody: () -> A): A- нельзя, посколькуType parameter A is declared as 'out' but occurs in 'in' position in type () -> Aabstract fun <B>getOrElse(elseBody: () -> B): B- можно, дляNoneработает (override fun <B>getOrElse(elseBody: () -> B): B = elseBody()), но дляSomeнельзя написатьoverride fun <B>getOrElse(elseBody: () -> B): B = value. Очевидно, чтоvalueне будет типомB
Как-то необходимо в определении абстрактного getOrElse связать A и B, но не как B : A, а в обратную сторону.
В Scala для этого используется т.н. lower bound: final def getOrElse[B >: A](default: => B): B, но как сделать аналог или эмуляцию lower bound в Kotlin?
Ответы (1 шт):
Напрямую, видимо, не получится. Но вполне рабочий вариант через использование расширения (extension). В прямолинейной реализации:
fun <A> Option<A>.getOrElse(elseBody: () -> A): A {
return if (this is Some<A>) {
this.get()
}
else {
elseBody()
}
}
Работает как нужно.