Kotlin Property: “Type parameter of a property mus

2020-06-09 04:04发布

问题:

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.

回答1:

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> // ??