Kotlin属性:“属性的类型参数必须在其接收器类型中使用” [英] Kotlin Property: "Type parameter of a property must be used in its receiver type"

查看:314
本文介绍了Kotlin属性:“属性的类型参数必须在其接收器类型中使用”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下简单的Kotlin扩展函数:

  //获取ViewGroup的视图
inline val ViewGroup .views:列表< View>
get()=(0..childCount - 1).map {getChildAt(it)}

//获取给定类型的ViewGroup的视图
内联乐趣<具体化T:查看> ViewGroup.getViewsOfType():列出< T> {
return this.views.filterIsInstance< T>()
}

此代码编译并正常工作。但是,我希望函数 getViewsOfType 成为一个属性,就像 views 一样。 Android Studio甚至建议它。我让AS进行重构,并生成以下代码:

  inline val< reified T:View> ViewGroup.viewsOfType:List< T> 
get()= this.views.filterIsInstance< T>()

不编译。它会导致错误:必须在接收器类型中使用属性的类型参数



这里有什么问题?寻找这个错误的帮助似乎没有得到答案。

解决方案

错误意味着您只能拥有一个如果您在接收器类型中使用所述类型 - 扩展属性的泛型类型参数 - 扩展类型。



例如,您可以有一个扩展名 T

  val< T:查看> T.propName:单元
get()=单元

T 作为参数: List< T> .propName:Unit
get()= Unit






至于这是为什么,我认为原因是一个属性不能像函数那样拥有泛型类型参数。虽然我们可以使用泛型类型参数调用一个函数...

  val buttons = viewGroup.getViewsOfType< Button>()

...我不相信类似的语法存在属性:

  val buttons = viewGroup.viewsOfType< Button> // ?? 


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

这篇关于Kotlin属性:“属性的类型参数必须在其接收器类型中使用”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆