【发布时间】:2020-11-30 13:12:27
【问题描述】:
简而言之:我想创建一个类型为 T 的泛型类,它应该调用类型为 T 的具体内联函数,以便能够更通用地使用 Gson
详细说明:
你好。我最近开始将 kotlin 用于 Android 开发,我正在尝试创建一个通用的网络客户端类。该类将从服务器获取数据,将响应转换为泛型类类型提供的数据类型并返回响应,如下所示:
class GenericNetworkService<RESPONSE_TYPE> {
fun getDataFromServer(url: String): RESPONSE_TYPE {
val request = Request.Builder().url(url).build()
val response = OkHttpClient().newCall(request).execute()
val convertor = Gson()
val result: RESPONSE_TYPE = convertor.fromJson(response.body!!.string(), RESPONSE_TYPE)
return result
}
}
//calling
//fun main() {
// val listOfPersons = GenericNetworkService<List<Person>>().getDataFromServer(url1)
// println(listOfPersons)
// val listOFTeacher = GenericNetworkService<List<Teacher>>().getDataFromServer(url2)
// println(listOFTeacher)
// }
在这里,只有gson.fromJson() func 是实际需要最终输出必须转换的类的详细信息的函数。 但它没有将泛型类型带入第二个参数,所以上面的程序不起作用。
在搜索了一些互联网文章后,我发现了这个TypeToken Api,它在一定程度上有助于实现通用行为:
inline fun <reified T> fromJson(json: String): T {
return Gson().fromJson(json, object: TypeToken<T>(){}.type)
}
//calling :
// val data : List<Teacher> = fromJson(response)
使用内联具体化函数,我能够实现我最初想要的一切:
private inline fun <reified RESPONSE_TYPE> getGenericRespSync(url: String): RESPONSE_TYPE {
val okHttpClient = generateNetworkClient()
val request = Request.Builder().url(url).build()
val response: Response = okHttpClient.newCall(request).execute()
val body: Reader = response.body!!.charStream()
val finalResponse: RESPONSE_TYPE = getConvertedListForResponse(body) //this is the same reified inline function as above with some non signinficant additions
return finalResponse
}
但我希望我的其他类通过某个类实例调用此函数。即像 GenericNetworkService<List<Person>>().getGenericRespSync(url1) 这样的东西应该返回 List 而不是直接调用 getGenericRespSync(url1) 。我怎样才能实现这样的功能?
【问题讨论】: