I have the following simple Kotlin extension functions:
// Get the views of ViewGroup
inline val ViewGroup.views: List<View>
get() = (0..childCount - 1).map { getChildAt(it) }
// Get the views of ViewGroup of given type
inline fun <reified T : View> ViewGroup.getViewsOfType() : List<T> {
return this.views.filterIsInstance<T>()
}
This code compiles and works fine. But, I want the function getViewsOfType
to be a property, just like the views
. Android Studio even suggests it. I let AS do the refactoring and it generates this code:
inline val <reified T : View> ViewGroup.viewsOfType: List<T>
get() = this.views.filterIsInstance<T>()
But this code doesn't compile. It causes error: "Type parameter of a property must be used in its receiver type"
What is the issue here? Searching for help on this error doesn't seem to lead to an answer.
The type parameter lets you specify exactly that—instead of “This variable holds a list,” you can say something like “This variable holds a list of strings.” Kotlin's syntax for saying “a list of strings” looks the same as in Java: List<String> . You can also declare multiple type parameters for a class.
"Out" keyword is extensively used in Kotlin generics. Its signature looks like this − List<out T> When a type parameter T of a class C is declared out, then C can safely be a super type of C<Derived>. That means, a Number type List can contain double, integer type list.
The error means that you can only have a generic type parameter for an extension property if you're using said type in the receiver type - the type that you're extending.
For example, you could have an extension that extends T
:
val <T: View> T.propName: Unit
get() = Unit
Or one that extends a type that uses T
as a parameter:
val <T: View> List<T>.propName: Unit
get() = Unit
As for why this is, I think the reason is that a property can't have a generic type parameter like a function can. While we can call a function with a generic type parameter...
val buttons = viewGroup.getViewsOfType<Button>()
... I don't believe a similar syntax exists for properties:
val buttons = viewGroup.viewsOfType<Button> // ??
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