我的问题是关于泛型方法的类型推断。
我有以下场景:
interface Obj {
val Id: String
}
data class User(override val Id: String, val name: String): Obj
data class Case(override val Id: String, val subject: String): Obj
interface Api {
fun <T: Obj> getLastUpdated(type: KClass<T>, backTill: Duration = Duration.ofDays(1)): LastUpdated
fun <T: Obj> getDetails(type: KClass<T>, uuid: String): Details<T>
data class LastUpdatedResponse(val ids: List<String> = emptyList(),
val latestDateCovered: String = "")
data class LastUpdated(val error: Throwable? = null, val response: LastUpdatedResponse? = null)
data class DetailsResponse<T>(val wrapped: T)
data class Details<T>(val error: Throwable? = null, val response: DetailsResponse<T>? = null)
}
在我的测试中,我需要确切地知道模拟的 API 需要返回什么,因此
val testCase = Case("123", "Testing")
val testUser = User("321", "Dummy")
val mockApi = object: Api {
override fun <T : Obj> getLastUpdated(type: KClass<T>, backTill: Duration): Api.LastUpdated {
return Api.LastUpdated(response = Api.LastUpdatedResponse(listOf("123")))
}
override fun <T : Obj> getDetails(type: KClass<T>, uuid: String): Details<T> {
when (type) {
Case::class -> return Api.Details(response = Api.DetailsResponse(wrapped = testCase)) // <- this fails
User::class -> return Api.Details(response = Api.DetailsResponse(wrapped = testUser)) // <- as does this
else -> return Api.Details(error = UnsupportedOperationException())
}
}
}
但是,这无法编译:
Error:(114, 43) Kotlin: Type inference failed. Expected type mismatch: inferred type is Api.Details<Case> but Api.Details<T> was expected
我可以通过强制转换使其工作:
when (type) {
Case::class -> return Api.Details(response = Api.DetailsResponse(wrapped = testCase)) as Api.Details<T>
User::class -> return Api.Details(response = Api.DetailsResponse(wrapped = testUser)) as Api.Details<T>
但随后我收到一条警告,通知我“此转换永远不会成功” - 运行我的测试,它确实按预期工作。
我的问题是 - 为什么在没有强制转换的情况下这不起作用?我应该使用什么来代替?
最佳答案
方差注释可能会帮助您,只需将以下函数中的泛型参数 T 更改为 out Obj(在接口(interface)和实现类中):
fun <T: Obj> getDetails(type: KClass<T>, uuid: String): Details<out Obj>
关于generics - 从泛型函数返回特定实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37727319/