具体化类型参数

Ktor reified type parametar

我在 kotlin 中使用泛型创建了 class 并希望将接收与泛型一起使用,但是当我想从泛型 call.recieve 输入时出现错误:

Can not use MType as reified type parameter. Use a class instead.

代码:

class APIRoute<EType : IntEntity, MType : Any> {
    fun Route.apiRoute() {
        post {
            val m = call.receive<MType>()
            call.respond(f(model))
        }
    }
}

如何解决?

您需要为 receive() 函数提供预期的类型。由于Java/Kotlin中的type erasureMType的类型在运行时是未知的,所以不能与receive()一起使用。构造APIRoute.

时需要捕获类型为KTypeKClass对象

KClass 更易于使用,但它仅适用于原始 类,不支持参数化类型。因此,我们可以使用它来创建例如APIRoute<*, String>,但不是 APIRoute<*, List<String>>KType 支持任何类型,但有点难处理。

KClass 的解决方案:

fun main() {
    val route = APIRoute<IntEntity, String>(String::class)
}

class APIRoute<EType : IntEntity, MType : Any>(
    private val mClass: KClass<MType>
) {
    fun Route.apiRoute() {
        post {
            val m = call.receive(mClass)
            call.respond(f(model))
        }
    }
}

KType的解决方案:

fun main() {
    val route = APIRoute.create<IntEntity, List<String>>()
}

class APIRoute<EType : IntEntity, MType : Any> @PublishedApi internal constructor(
    private val mType: KType
) {
    companion object {
        @OptIn(ExperimentalStdlibApi::class)
        inline fun <EType : IntEntity, reified MType : Any> create(): APIRoute<EType, MType> = APIRoute(typeOf<MType>())
    }

    fun Route.apiRoute() {
        post {
            val m = call.receive<MType>(mType)
            call.respond(f(model))
        }
    }
}