PHaroZ
09/07/2020, 1:01 PMdata class ValueHolder<A> (val value: A){
@OptIn(ExperimentalContracts::class)
inline fun <reified B : A> valueIs(): Boolean {
contract {
returns(true) implies (this@ValueHolder is ValueHolder<B>) // <- compiler error here "Cannot check for instance of erased type: ValueHolder<B>"
}
return value is B
}
}
the goal is to use #valueIs
in a when statement and benefit of smart-casting in branch as
when {
valueHolder.valueIs<TypeA> -> doStuffWithAHolder(valueHolder)
valueHolder.valueIs<TypeB> -> doStuffWithBHolder(valueHolder)
}
Michael de Kaste
09/07/2020, 1:12 PMPHaroZ
09/07/2020, 1:24 PMis ParsingContext<B>
with is ParsingContext
(which is of no interest anymore)Michael de Kaste
09/07/2020, 1:27 PMPHaroZ
09/07/2020, 1:28 PMdmitriy.novozhilov
09/07/2020, 1:38 PMB
is reified, ValueHolder
is still generic class, so all actual type parameters will be erased at runtime. So check this is ValueHolder<B>
is equal to this is ValueHolder<Any>
Michael de Kaste
09/07/2020, 1:39 PMPHaroZ
09/07/2020, 1:46 PMdmitriy.novozhilov
09/07/2020, 2:24 PMPHaroZ
09/07/2020, 6:07 PMPHaroZ
09/08/2020, 3:01 AMdata class ValueHolder<A> (val value: A){
@Suppress("UNCHECKED_CAST")
fun <B : A> narrow() = this as ValueHolder<B>
}
when (valueHolder.value) {
is TypeA -> doStuffWithAHolder(valueHolder.narrow())
is TypeB -> doStuffWithBHolder(valueHolder.narrow())
}
Thx to the powerfull type-inference of kotlin compiler :)