Generic programming 如何在Kotlin中检查泛型类型
我正在测试Kotlin中的泛型类型Generic programming 如何在Kotlin中检查泛型类型,generic-programming,kotlin,Generic Programming,Kotlin,我正在测试Kotlin中的泛型类型 if (value is Map<String, Any>) { ... } 使用Kotlin 0.4.68 我在这里遗漏了什么?问题是类型参数被删除,因此无法对照完整的类型映射进行检查,因为在运行时没有关于这些字符串和任何类型的信息 要解决此问题,请使用通配符: if (value is Map<*, *>) {...} 如果(值是Map){…} JVM删除泛型类型信息。但科特林已经具体化了仿制药。如果您有一个泛型类型T,您可以将
if (value is Map<String, Any>) { ... }
使用Kotlin 0.4.68
我在这里遗漏了什么?问题是类型参数被删除,因此无法对照完整的类型映射进行检查,因为在运行时没有关于这些字符串和任何类型的信息 要解决此问题,请使用通配符:
if (value is Map<*, *>) {...}
如果(值是Map){…}
JVM删除泛型类型信息。但科特林已经具体化了仿制药。如果您有一个泛型类型T,您可以将内联函数的类型参数T标记为具体化,以便它能够在运行时检查它
因此,您可以:
inline fun <reified T> checkType(obj: Object, contract: T) {
if (obj is T) {
// object implements the contract type T
}
}
inline-fun-checkType(obj:Object,contract:T){
if(obj是T){
//对象实现契约类型T
}
}
我认为这是更合适的方法
inline fun <reified T> tryCast(instance: Any?, block: T.() -> Unit) {
if (instance is T) {
block(instance)
}
}
inline fun tryCast(实例:Any?,块:T.()->Unit){
if(实例为T){
块(实例)
}
}
用法
//myVar可为空
tryCast(myVar){
//该怎么办。
this.canDoSomething()
}
另一种较短的方法
inline fun <reified T> Any?.tryCast(block: T.() -> Unit) {
if (this is T) {
block()
}
}
inline fun Any?.tryCast(块:T.()->单位){
如果(这是T){
块()
}
}
用法
//myVar可为空
myVar.tryCast{
//该怎么办。
this.canDoSomething()
}
我用tryCast
尝试了上面的解决方案,我想,在我的具体任务中,列出了许多涉及到的铸件,这并不是什么好主意,因为它大大降低了性能
这是我最后做的解决方案-手动检查条目和调用方法,如下所示:
fun foo() {
val map: Map<String?, Any?> = mapOf()
map.forEach { entry ->
when (entry.value) {
is String -> {
doSomeWork(entry.key, entry.value as String)
}
is Array<*> -> {
doSomeWork(entry.key, (entry.value as? Array<*>)?.map {
if (it is String) {
it
} else null
}?.toList())
}
}
}
}
private fun doSomeWork(key: String?, value: String) {
}
private fun doSomeWork(key: String?, values: List<String?>?) {
}
fun foo(){
val-map:map=mapOf()
map.forEach{entry->
何时(entry.value){
是字符串->{
doSomeWork(entry.key、entry.value作为字符串)
}
是数组->{
doSomeWork(entry.key,(entry.value作为数组)?.map{
如果(它是字符串){
信息技术
}否则无效
}?.toList())
}
}
}
}
私人娱乐doSomeWork(键:String?,值:String){
}
私人娱乐doSomeWork(键:字符串?,值:列表?){
}
太棒了!那太好了!我只是被文档中的示例弄糊涂了:如果您真的想检查某个东西是否是集合
以使其自动转换,该怎么办?我有这样的代码片段if(it.getSerializable(ARG_PARAMS)是HashMap){it.getSerializable(ARG_PARAMS)作为HashMap}else null
。所以基本上,如果我检查泛型类型,它会尝试将HashMap
转换为HashMap
。我遗漏了什么吗?@FARID是的,会的,而且这种类型的强制转换是不安全的。你能举例说明如何调用checkType()
?我不确定第二个参数应该传递什么。@MichaelOsofskycheckType(MyMapOfstring,Map)
为什么这样的东西在kotlin stdlib中不直接可用:-(难道与?String
不一样吗?@DaliborFilus nope.后面的问号不一样。这是关于泛型和运行时被擦除的类型。如果你不需要处理泛型,你可以直接使用作为?
,正确。
inline fun <reified T> Any?.tryCast(block: T.() -> Unit) {
if (this is T) {
block()
}
}
// myVar is nullable
myVar.tryCast<MyType> {
// todo with this e.g.
this.canDoSomething()
}
fun foo() {
val map: Map<String?, Any?> = mapOf()
map.forEach { entry ->
when (entry.value) {
is String -> {
doSomeWork(entry.key, entry.value as String)
}
is Array<*> -> {
doSomeWork(entry.key, (entry.value as? Array<*>)?.map {
if (it is String) {
it
} else null
}?.toList())
}
}
}
}
private fun doSomeWork(key: String?, value: String) {
}
private fun doSomeWork(key: String?, values: List<String?>?) {
}