Error al usar un object para implementar una list vacía
Estoy tratando de reescribir la interfaz de la Lista como un ejercicio para aprender la Progtwigción Funcional en Kotlin, pero no puedo entender por qué me sale un error cuando bash tener un object como la list vacía, que no ocurre en la biblioteca estándar de Kotlin. En mi código, ver a continuación, quiero usar NIL como una list vacía singleton, usando list () como la function para devolverlo. Sin embargo, esto genera un error de desajuste de tipo en la function de tipo "Lista requerida. Encontrado NIL".
interface List<A> { val empty: Boolean val head: A val tail: List<A> fun cons(a: A): List<A> = Cons(a, this) } object NIL : List<Nothing> { override val empty: Boolean = true override val head: Nothing get() = throw IllegalStateException("head called on empty list") override val tail: List<Nothing> get() = throw IllegalStateException("tail called on empty list") } private class Cons<A>(override val head: A, override val tail: List<A>) : List<A> { override val empty: Boolean = false } fun <A> list(): List<A> = NIL // Type mismatch. Requinetworking: List<A>. Found: NIL fun <A> list(vararg a: A): List<A> { var n = list<A>() for (e in a.reversed()) { n = Cons(e, n) } return n }
En la biblioteca estándar, este error no ocurre, como puede ver en EmptyList en Collections.kt . ¿Estoy haciendo algo mal o me faltan algunos conceptos que hacen que este último sea posible y el anterior no?
- Los generics de kotlin tienen que escribir el parámetro de tipo
- Kotlin Constructor Crash
- Kotlin: ¿cómo hacer una propiedad delegada por map con un nombre personalizado?
- Dividir algorithm y ver parte usando un Patrón de estrategia en Kotlin
- El module de Dagger no funciona después de la conversión de Java a Kotlin
Evaluación de soluciones propuestas
De las tres soluciones propuestas, la única que permite pasar el código de testing a continuación es la que usa el object anónimo , mientras que las otras arrojan la exception java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Void
.
assertEquals("a", list<String>().cons("a").head)
Sin embargo, si cambio NIL
a NIL : List<Any?>
, La solución NIL as List<A>
funciona sin ningún problema.
- Usando kotlin-stdlib 1.1.51 pero se carga kotlin-runtime 1.3
- Fuel, Kotlin, Gson, se esperaba BEGIN_ARRAY pero era BEGIN_OBJECT en la línea 1
- Cómo resolver: Error: ejecución fallida para la tarea ': aplicación: kaptDebugKotlin'?
- No se puede encontrar el cuerpo de destino después de ejecutar una aplicación web de Jfinal con kotlin
- Disruptor LMAX con Kotlin: ¿No se puede usar lambda?
- Transferencia de files Java a Kotlin en Android Studio
- No se puede convertir a colección en kotlin
- Cómo animar una list de animation en Kotlin?
puede convertir una List<Nothing>
en una List<A>
explícita por una palabra key, por ejemplo:
fun <A> list(): List<A> = NIL as List<A>;
SI desea suprimir las advertencias del comstackdor, puede anotar la function con la anotación @Suppress
, por ejemplo:
@Suppress("UNCHECKED_CAST") fun <A> list(): List<A> = NIL as List<A>;
O si no te gusta de esta manera, puedes usar un object anónimo en una function, por ejemplo:
fun <A> list(): List<A> = object : List<A> { override val empty: Boolean = true override val head: A get() = throw IllegalStateException("head called on empty list") override val tail: List<A> get() = throw IllegalStateException("tail called on empty list") };
Generic en su interfaz debe ser <out A>
lugar de <A>
.
Además, IntelliJ Idea muestra una advertencia cuando utiliza generics sin variación en esos casos.
- Kotlin: delegación de funciones
- ¿Por qué Android Studio convierte algunos types primitivos de Kotlin como operador condicional / seguro?