The second to last line doesn't compile but the last line compiles fine:
return if(true) m1 else m2 will compile?Compile error:
Type mismatch: inferred type is
Hold<HelloMsg>butHold<Msg>was expected
interface Msg
class HelloMsg: Msg
class ByeMsg: Msg
class Hold<T: Msg>(val msg: T)
fun test(): Hold<Msg> {
val m1 = Hold(HelloMsg())
val m2 = Hold(ByeMsg())
return if(true) m1 else m2 //DOESN'T COMPILE
return if(true) Hold(HelloMsg()) else Hold(ByeMsg()) //COMPILES
}
What can I change so that return if(true) m1 else m2 will compile?
Make Hold covariant: class Hold<out T: Msg>(val msg: T). Then Hold<HelloMsg> and Hold<ByeMsg> will both be subtypes of Hold<Msg>.
I think I have the answer to my second question:
fun test(): Hold<out Msg> { ... }
Yes, that works too, but more locally. class Hold<out T> is basically equivalent to making all uses of Hold marked with out.
What is the reason (they seem equivalent to me)?
In the if(true) m1 else m2 case the types of m1 and m2 are already fixed by their declaration and different from Hold<Msg>.
In the if(true) Hold(HelloMsg()) else Hold(ByeMsg()) the compiler is typing Hold(HelloMsg()) while knowing it has to be Hold<Msg>. So it infers the type parameter as Hold<Msg>(HelloMsg()). Same with the other branch.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With