Assum I have this extension function:
inline fun <reified R> Any.getPrivateProperty(variableName: String): R { … }
I can quite conveniently call this with something like s.getPrivateProperty<Int>("height"), an expression that is of type Int.
Now I wanted to make sure the function is only defined on non-optional types. I used the definitely-not-nullable notation:
inline fun <T: Any, reified R> T.getPrivateProperty(variableName: String): R { … }
This fulfills the purpose, however, since I have that one type parameter which must be explicit, I actually have to give both now. Example: s.getPrivateProperty<Shape, Int>("height").
Is it even possible to avoid that in general? Is there an alternative way to avoid that here, that is, to only define the extension function over non-optional types?
>Solution :
The first version of the function already does not work on nullable types. For example, this doesn’t compile.
val x: String? = "foo"
val y = x.getPrivateProperty<String>("foo")
In general, when calling a function, you must specify all the type parameters in the <...> part, or you must let all of them be inferred.
There are ways to infer R in this case though. It needs not be always written in <>. Simply do:
val y: String = x.getPrivateProperty("foo")
// ^^^^^^
That is, since R is the return type, you can just write it as the type of the variable you are assigning to.
For non-return types, if for some reason Kotlin can’t infer them, a simple way to "infer" them is to pass a Dummy<T>, to let the caller specify.
class Dummy<T>
// imagine foo having some other parameters using T and U,
// but T can't be inferred for whatever reason, but U can be inferred
// you can just add an extra parameter of type Dummy<T>
fun <T, U> foo(... other parameters ..., t: Dummy<T>) { ... }
Then the caller can do:
foo(..., Dummy<SomeType>())
without having to specify U as well.
For non-nullable type parameters, you can use KClass<T> instead of creating your own Dummy<T>.