Estoy tratando de probar un tipo genérico en Kotlin.
if (value is Map<String, Any>) { ... }
Pero el compilador se queja con
No se puede comprobar, por ejemplo, el tipo borrado: jet.Map
La comprobación con un tipo normal funciona bien.
if (value is String) { ... }
Se utiliza Kotlin 0.4.68.
¿Que me estoy perdiendo aqui?
generic-programming
kotlin
Philipp Brüll
fuente
fuente
Collection<String>
lanzamiento automático?if (it.getSerializable(ARG_PARAMS) is HashMap<*, *>) {it.getSerializable(ARG_PARAMS) as HashMap<String, String>} else null
. Así que básicamente se va a tratar de fundiciónHashMap<String, Integer>
aHashMap<String, String>
si yo estoy comprobando contra el tipo genérico. ¿Me estoy perdiendo de algo?JVM elimina la información de tipo genérico. Pero Kotlin ha cosificado los genéricos. Si tiene un tipo genérico T, puede marcar el parámetro de tipo T de una función en línea como reificado para que pueda verificarlo en tiempo de ejecución.
Entonces puedes hacer:
inline fun <reified T> checkType(obj: Object, contract: T) { if (obj is T) { // object implements the contract type T } }
fuente
checkType()
? No estoy seguro de qué pasar por el segundo argumento.Creo que esta es la forma más apropiada
inline fun <reified T> tryCast(instance: Any?, block: T.() -> Unit) { if (instance is T) { block(instance) } }
Uso
// myVar is nullable tryCast<MyType>(myVar) { // todo with this e.g. this.canDoSomething() }
Otro enfoque más corto
inline fun <reified T> Any?.tryCast(block: T.() -> Unit) { if (this is T) { block() } }
Uso
// myVar is nullable myVar.tryCast<MyType> { // todo with this e.g. this.canDoSomething() }
fuente
something as? String
mismo? Tenga en cuenta el signo de interrogación después deas
?as?
, corregir.Probé la solución anterior con
tryCast<Array<String?>>
y, supongo, en mi tarea específica de enumerar con muchos castings involucrados no fue tan buena idea, porque estaba ralentizando drásticamente el rendimiento.Esta es la solución que hice finalmente: verifique manualmente las entradas y los métodos de llamada, como este:
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?>?) { }
fuente