如何将类型传递给 Kotlin 中的泛型方法?
How to pass a type to generic method in Kotlin?
我有一个如下所示的通用方法
private fun <T> getSomething(): T {
return "something" as T
}
如何使用 T
类型的变量调用此方法?
val types = arrayListOf<Type>(String::class.java, Boolean::class.java)
types.forEach { type ->
val something = getSomething<type>() // Unresolved reference: type
}
在运行时,我不知道泛型类型是什么T
。我从 types
获取类型,应该使用通用 getSomething
方法传递它。
用例
我想调用有几个table的数据库。示例模型是这样的
class User{
}
class Student{
}
由于所有的调用查询基本相同,我想有一个通用的方法来调用数据库和获取数据。
private fun <T> getData(model: String): List<T>?{
return when(model){
"user" -> getUsers()
"student" -> getStudents()
else -> null
}
}
所以当我调用上面的方法时。在我的循环中,我想将 Type
作为 User
或 Student
.
传递
val types = arrayListOf<Type>(User::class.java, Student::class.java)
types.forEach { type ->
val data = getData<type>(type.javaClass.simpleName) // Unresolved reference: type in <type>
}
如何实现。
这是一个完整的例子:
import kotlin.reflect.KClass
data class User(val name: String)
data class Student(val name: String)
fun getUsers(): List<User> = listOf(User("JB"))
fun getStudents(): List<Student> = listOf(Student("Claire"))
fun <T: Any> getData(clazz: KClass<T>): List<T>? {
return when(clazz) {
User::class -> getUsers() as List<T>
Student::class -> getStudents() as List<T>
else -> null
}
}
fun main(args: Array<String>) {
val types = listOf(User::class, Student::class)
types.forEach { type ->
val data = getData(type)
println(data)
}
}
我会坚持使用像
这样的具体类型
import kotlin.reflect.KClass
interface IBaseData
interface IDataTable<out T> where T : IBaseData
{
fun getData(): List<T>
}
class User : IBaseData
class Student : IBaseData
class UserTable : IDataTable<User>
{
override fun getData(): List<User>
{
return listOf(User())
}
}
class StudentTable : IDataTable<Student>
{
override fun getData(): List<Student>
{
return listOf(Student())
}
}
inline fun <reified T: IBaseData> getDataTable() : IDataTable<T>?
{
return when(T::class)
{
User::class -> UserTable() as IDataTable<T>
Student::class -> StudentTable() as IDataTable<T>
else -> null
}
}
fun main()
{
var user = getDataTable<User>()?.getData()
var student = getDataTable<Student>()?.getData()
}
但是,这仍然是一个开销,为什么不直接使用 getUser()
或 getStudents()
我有一个如下所示的通用方法
private fun <T> getSomething(): T {
return "something" as T
}
如何使用 T
类型的变量调用此方法?
val types = arrayListOf<Type>(String::class.java, Boolean::class.java)
types.forEach { type ->
val something = getSomething<type>() // Unresolved reference: type
}
在运行时,我不知道泛型类型是什么T
。我从 types
获取类型,应该使用通用 getSomething
方法传递它。
用例
我想调用有几个table的数据库。示例模型是这样的
class User{
}
class Student{
}
由于所有的调用查询基本相同,我想有一个通用的方法来调用数据库和获取数据。
private fun <T> getData(model: String): List<T>?{
return when(model){
"user" -> getUsers()
"student" -> getStudents()
else -> null
}
}
所以当我调用上面的方法时。在我的循环中,我想将 Type
作为 User
或 Student
.
val types = arrayListOf<Type>(User::class.java, Student::class.java)
types.forEach { type ->
val data = getData<type>(type.javaClass.simpleName) // Unresolved reference: type in <type>
}
如何实现。
这是一个完整的例子:
import kotlin.reflect.KClass
data class User(val name: String)
data class Student(val name: String)
fun getUsers(): List<User> = listOf(User("JB"))
fun getStudents(): List<Student> = listOf(Student("Claire"))
fun <T: Any> getData(clazz: KClass<T>): List<T>? {
return when(clazz) {
User::class -> getUsers() as List<T>
Student::class -> getStudents() as List<T>
else -> null
}
}
fun main(args: Array<String>) {
val types = listOf(User::class, Student::class)
types.forEach { type ->
val data = getData(type)
println(data)
}
}
我会坚持使用像
这样的具体类型import kotlin.reflect.KClass
interface IBaseData
interface IDataTable<out T> where T : IBaseData
{
fun getData(): List<T>
}
class User : IBaseData
class Student : IBaseData
class UserTable : IDataTable<User>
{
override fun getData(): List<User>
{
return listOf(User())
}
}
class StudentTable : IDataTable<Student>
{
override fun getData(): List<Student>
{
return listOf(Student())
}
}
inline fun <reified T: IBaseData> getDataTable() : IDataTable<T>?
{
return when(T::class)
{
User::class -> UserTable() as IDataTable<T>
Student::class -> StudentTable() as IDataTable<T>
else -> null
}
}
fun main()
{
var user = getDataTable<User>()?.getData()
var student = getDataTable<Student>()?.getData()
}
但是,这仍然是一个开销,为什么不直接使用 getUser()
或 getStudents()