【问题标题】:Get a parameter of a parametrized type in Kotlin在 Kotlin 中获取参数化类型的参数
【发布时间】:2021-03-30 06:53:40
【问题描述】:

所以我有一个泛型类型的类

class GenericClass<T> {
// At some point in the class I have variable item of type T
val name: String = item.name
}

我确信 GenericClass 的类型 T 将与具有“名称”属性的类一起使用。但当然,我得到了一个“未解决的参考名称”。 Android Studio 通过“创建扩展属性 T.name”为我生成了这段代码

private val <T> T.name: String
    get() {}

我真的不知道在 get 之后在括号 {} 中放什么。我尝试了return name,但出现递归属性错误。

有什么想法吗?

谢谢

【问题讨论】:

    标签: kotlin generics member


    【解决方案1】:

    如果你知道每个类型 T 都有属性 name 你可以隐式声明它:

    // GenericClass.kt
    class GenericClass<T : HasName> {
        // At some point in the class I have variable item of type T
        val name: String = item.name
    }
    
    // HasName.kt
    // Create new interface with "name" property
    interface HasName {
        val name: String
    }
    

    但您还必须为所有可以用作 T 的类实现这个新接口。

    【讨论】:

    • 嗯。这里的重点是方法/属性的名称是无关紧要的;只有存在继承关系时,Kotlin 才会将它们视为相同。 (从技术角度来说,Kotlin 没有 structural typing。)  所以如果两个 Ts 都恰好有一个名为 name 的属性并不重要——除非它们实现了相同的接口(或扩展了相同的类) ,那么它们是不相关的方法,只是碰巧拼写相同,您不能以相同的方式称呼它们。另请参阅this question
    • 这里的 HasName 接口不就是 @gidds 实现的吗?
    • @mattfreake 没错!这就是问题中的代码不起作用的原因——也是这个答案起作用的原因。
    • 啊抱歉我误会了你 :-) 我以为你在批评这个答案。
    【解决方案2】:

    我确信 GenericClass 的类型 T 将与具有“名称”属性的类一起使用。

    然后你需要明确声明。默认情况下,T 扩展 Any?。您需要通过声明一些接口来缩小T 的可能类型,例如

    interface Named {
        val name : String
    }
    

    并将T : Named 作为通用参数传递。此外,您需要创建所有类,您将作为通用参数传递,以实现该接口。顺便说一句,GenericClass&lt;T : Named&gt; 类本身可以声明为实现该接口:

    class GenericClass<T : Named> : Named {
        override val name: String = item.name
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 2016-07-15
      • 2018-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多