Как передать тип в универсальный метод в Kotlin? - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть универсальный метод, как показано ниже

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.

Вариант использования

Я хочу вызвать базу данных, в которой есть несколько таблиц.Примеры моделей выглядят так:

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>
}

Как мне этого добиться.

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Я бы придерживался конкретных типов, таких как

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 непосредственно

0 голосов
/ 03 декабря 2018

Вот полный пример:

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)
    }
}
...