kotlin - Kotlin 中的泛型和内联函数

标签 kotlin generics

我在 Kotlin 中使用泛型时遇到困难。 我想制作通用接口(interface)和实现以及几个特定类型的 DAO。

// Type parametrized DAO
interface DaoInterface<T : Any> {
    fun <T : Any> getByCollectionId(collectionId: Long, clazz: Class<T>): List<T>
}

//Generic DAO implementation
open class DaoInterfaceImpl<T : Any>(private val entityManager: EntityManager) : DaoInterface<T> {
    override fun <T : Any> getByCollectionId(collectionId: Long, clazz: Class<T>): List<T> =
        entityManager.createQuery(
            "from ${clazz.name} c where c.collectionId = :collectionId", clazz
        )
            .apply { setParameter("collectionId", collectionId) }
            .resultList ?: listOf()

    inline fun <reified T : Any> getByCollectionId(collectionId: Long): List<T> =
        getByCollectionId(collectionId, T::class.java)
}

//Type specified DAO
class TestContactDao(entityManager: EntityManager) : DaoInterface<Contacts>, DaoInterfaceImpl<Contacts>(entityManager)

class Test(private val testContactDao: TestContactDao) {
    fun call() {
        val result1 = testContactDao.getByCollectionId<Contacts>(123L)
        val result2 : List<Contacts> = testContactDao.getByCollectionId(123L)
        val result3 = testContactDao.getByCollectionId(123L)
    }
}

result1 和 result2 工作正常,但在 result3 中我收到“类型推断失败”错误。

我不想在这些调用中指定泛型(如 result1 和 2)。我想为不同的类(联系人、地址等)创建多个 DAO,并像 result3 中那样调用它们。

我该怎么做?

最佳答案

问题在于,当您重新定义该类型变量时,具体化的 T 与类类型 T 不匹配。您仍然可以通过在接口(interface)上定义扩展函数来避免传递 Class:

// helper extension to simplify access
inline fun <reified T> DaoInterface<T>.getByCollectionId(collectionId: Long): List<T> = getByCollectionId(collectionId, T::class.java)

为什么这有效?在这里,我们将 T 定义为具体化,并指定 DaoInterface 必须具有相同的类型 T

我有一个在这里工作的 Playground 示例:https://pl.kotl.in/kLiM9xD3y

关于kotlin - Kotlin 中的泛型和内联函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70845398/

相关文章:

java - 地理围栏在 Kotlin 中不起作用

gradle - Kotlin DSL 中的 gradle 额外属性是如何设置的?

sqlite - 如何在 Kotlin/Native 中使用 SQLite?

swift - Swift 中是否可以自定义合成条件一致性?

java - 通用对象链表 (Java)

android - org.jetbrains.kotlin.util.KotlinFrontEndException :

java - Java 中的泛型方法 : "Object does not take parameters"

java - 在方法中获取请求泛型类型

c# 泛型类和方法未按预期运行

functional-programming - Kotlin arrow-kt 展平嵌套的 Either