泛型函数返回指定类型的List

时间:2019-09-01 05:34:26

标签: generics kotlin

下面的代码段返回类类型Object,因此不需要强制转换。

fun <T: Any> getData(clazz: KClass<T>): T? {

}

// Calling function
val article = getData(Article::class)
article.read == true      // Call function is possible without casting

现在,我要返回的是List和特定的Type。但是,由于::class的左侧应该是唯一的类,因此我无法传递类似List<Article>::class的内容。

如何解决?

方法1。创建一个扩展List<Article>的类并将该类作为参数传递

class ArticleList: ArrayList<Article>


fun <T: Any> getData(clazz: KClass<T>): T? {

}

// Calling function
val articleList = getData(ArticleList::class)
articleList[0].read == true      // Call function is possible without casting

方法2。每次调用时,将getData()函数的输入参数更改为Type,并在getData()函数前面添加paramaterType。

fun <T: Any> getData(type: Type): T? {
} 

// Calling function
val listType = object : TypeToken<ArrayList<Article>>() {}.type
val data = getData<List<Article>>(listType)
data[0].read == 1     // Call function is possible without casting

当前,我试图避免使用方法1 ,因为我最终将为每个项目创建一个类,而方法2 已经是一种强制转换。

还有其他解决方案可以以最简单的方式实现吗?

2 个答案:

答案 0 :(得分:2)

顺便说一句,您可以使用reified函数的inline类型参数不传递KClass对象:

inline fun <reified T> getData(): T? {
    // do something with T::class
}

这不是理想的解决方案,但是您可以创建其他getDataList函数:

inline fun <reified T> getDataList(): List<T> {
    val listType = TypeToken.getParameterized(List::class.java, T::class.java)
    // do something
}

答案 1 :(得分:0)

传递实际类型而不是传递类型参数的开销是多少?

由于我也是Kotlin的新手。这就是我想出的。

class Article {
    var read = false
}

inline fun <reified T> getData() : T? {
    //how do I generically instantiate T, I don't have constructor info here
    for(con in T::class.java.constructors) {
        if(con.parameterCount == 0) {
            return con.newInstance() as T
        }
    }
    return null
}
fun main(){
    val article = getData<Article>() 
    article?.read = true
    var articleList = getData<ArrayList<Article>>() 
    article?.let{
        articleList?.add(it)
    }
    print(articleList)
}