kotlin - 将数据类型作为参数传递给函数
问题描述
我正在使用 GSON 通过以下方式解析 JSON:
var obj = Gson().fromJson( json, Array<MyDataModel>::class.java ).toList()
我希望能够通过以下方式通过方法传递数据类型:
fun convert( t : Any ) : Any
{
return Gson().fromJson( mockedResponse, t ).toList()
}
val model = convert( Array<MyDataModel>::class.java )
但我得到:
None of the following functions can be called with the arguments supplied
我也尝试将Type作为参数数据类型,但同样的错误仍然存在。如何将 DataType 传递给我的转换方法?谢谢!
解决方案
这里发生了几件事。
首先,传递类型的传统方式是传递其KClass
对象(using ::type
)或Class
对象(using ::type.class
)。
所以你可以将你的函数声明为:
fun convert(t: Class<*>): Any
但这会产生一个新问题:Gson().fromJson()
返回您指定类型的对象。在这种情况下,它可以是任何东西(因此是*
),因此编译器不知道您是否可以调用toList()
它。
对此的一种解决方案是提供类型绑定,例如:
fun <T: Collection<U>, U> convert(t: Class<T>): List<U>
这指定您传递的类型必须是 的某个实现Collection
,并且它返回List
具有相同元素类型的 a。因为Collection
有一个toList()
方法,所以一切都有效。
但是,这不适用于您传递Array
类型的情况,因为数组没有toList()
方法。(Array
类型在 Kotlin 中有点尴尬。它们主要是为了向后兼容 Java;List
s 在很多方面都更好。)
您可以使用上述内容,并直接使用 List 类型。但是,您将无法指定 List 元素类型:
fun <T: Collection<U>, U> convert(t: Class<T>): List<U> {
return Gson().fromJson(mockedResponse, t).toList()
}
val model: List<*> = convert(List::class.java)
所以最好toList()
在你的函数中删除,而不是限制类型。这样,调用者可以进行任何需要的转换,从而保留元素类型:
fun <T> convert(t: Class<T>): T {
return Gson().fromJson(mockedResponse, t)
}
val model: List<MyDataModel> = convert(Array<MyDataModel>::class.java).toList()
作为最后的调整,我们可以使用 Kotlin 的另一种更简洁的方式来传递类型:使它们具体化。这种替换是在编译时完成的,而不是在运行时完成的,并且只适用于inline
函数:
inline fun <reified T> convert(): T {
return Gson().fromJson(mockedResponse, T::class.java)
}
val model: List<MyDataModel> = convert<Array<MyDataModel>>().toList()
推荐阅读
- c# - NUnit 测试无法识别我创建的类 - “找不到类型或命名空间名称”
- python - 不确定为什么趋势线没有出现在 matplotlib 散点图上
- react-native - ImagePicker 说我没有相机胶卷权限,但我找不到有关这些的任何文档
- r - 如何在带有数据帧(数据表)列名向量的循环中按索引排序?
- javascript - 获取特定字符之间的替换
- django - post方法如何获取外键字段名?
- d3.js - 两级进入/更新/退出,无嵌套
- python - 为什么我会收到 RuntimeError: CUDA error: invalid argument in pytorch?
- nativescript - RadListView 结合了滑动和单击(按)
- vim - Vim 用一个空行替换多个空行