Szymon Jeziorski
11/11/2022, 7:40 PMpublic inline fun <R, T : R> Result<T>.getOrElse(onFailure: (exception: Throwable) -> R): R
From the signature I would think that since T
is of type R
or its subtype, on Result<SubClass>
instance I could invoke getOrElse
only by passing lambda returning value of type which is super type to SubClass
.
Below code compiles perfectly fine, and I'm not sure why:
val x: Result<CharSequence> = runCatching { "string value" }
val z = x.getOrElse { 123 }
it would be logical for me that only lambdas returning super type of CharSequence
should be accepted, but I can pass whatever return type I want and this still works fine, it just makes inferred type of z
Result<Any>
. Am I missing something or should this not be expected behavior? Also, I cannot understand reason behind T : R
within function's declaration, if anything R : T
would be more logical to my understanding.ephemient
11/11/2022, 7:44 PMclass Result<out T>
, a Result<CharSequence>
is a Result<Any>
Szymon Jeziorski
11/11/2022, 7:53 PMfun <R, T : R> genericFunction(first: T, second: R): R = second
open class BaseClass(val name: String)
class SubClass(val secondName: String, name: String) : BaseClass(name)
val base = BaseClass("name")
val derived = SubClass("secondName", "name")
val firstCall = genericFunction(base, derived) // inferred type is BaseClass
val secondCall = genericFunction(derived, base) // inferred type is BaseClass
val thirdCall = genericFunction(base, "string") // inferred type is Any
it would be logical for me that third call shouldn't be possible as BaseClass
is not a subtype of String
Could you advice further?ephemient
11/11/2022, 7:55 PMgenericFunction<Any, BaseClass>()
. there's no reason the compiler needs to choose the narrowest possible type for each generic parameter in isolation - in fact, in many cases it must not. instead, it tries to find the narrowest type that satisfies the expression.Szymon Jeziorski
11/11/2022, 7:57 PM