Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

410
Vistas
Problema de Kotlin al delegar en el mapa con DefaultValue - ¿Error de idioma?

En el siguiente código, donde MyMap implementa de manera trivial Map by delegación a impl :

 foo@host:/tmp$ cat Foo.kt class MyMap <K, V> (val impl : Map <K, V>) : Map<K, V> by impl { fun myGetValue (k: K) = impl.getValue(k) } fun main() { val my_map = MyMap(mapOf('a' to 1, 'b' to 2).withDefault { 42 }) println(my_map.myGetValue('c')) // OK println(my_map.getValue('c')) // ERROR }

¿Por qué aparece el siguiente error en la segunda impresión?

 foo@host:/tmp$ /path/to/kotlinc Foo.kt foo@host:/tmp$ /path/to/kotlin FooKt 42 Exception in thread "main" java.util.NoSuchElementException: Key c is missing in the map. at kotlin.collections.MapsKt__MapWithDefaultKt.getOrImplicitDefaultNullable(MapWithDefault.kt:24) at kotlin.collections.MapsKt__MapsKt.getValue(Maps.kt:344) at FooKt.main(Foo.kt:8) at FooKt.main(Foo.kt) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.jetbrains.kotlin.runner.AbstractRunner.run(runners.kt:64) at org.jetbrains.kotlin.runner.Main.run(Main.kt:176) at org.jetbrains.kotlin.runner.Main.main(Main.kt:186) foo@bigdev:/tmp$

Actualización: los resultados de la versión del compilador y del tiempo de ejecución son:

 foo@host:/tmp$ kotlinc -version info: kotlinc-jvm 1.6.10 (JRE 17.0.1+12-LTS) foo@host:/tmp$ kotlin -version Kotlin version 1.6.10-release-923 (JRE 17.0.1+12-LTS) foo@host:/tmp$ javac -version javac 17.0.1 foo@host:/tmp$ java -version openjdk version "17.0.1" 2021-10-19 LTS OpenJDK Runtime Environment Corretto-17.0.1.12.1 (build 17.0.1+12-LTS) OpenJDK 64-Bit Server VM Corretto-17.0.1.12.1 (build 17.0.1+12-LTS, mixed mode, sharing)
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Aunque hubiera esperado que su código funcionara para ser honesto, esto podría ser un error , pero tendríamos que mirar el código de bytes producido.

En la documentación dice (énfasis mío):

Este valor predeterminado implícito se usa cuando el mapa original no contiene un valor para la clave especificada y se obtiene un valor con la función Map.getValue , por ejemplo, cuando las propiedades se delegan al mapa.

El conflicto de "contratos" proviene de la interfaz del Map real, que dice:

 Returns the value corresponding to the given [key], or null if such a key is not present in the map.

El contrato predeterminado de mapas debe cumplir con esto, por lo que "solo" puede devolver un valor nulo cuando una clave no existe.

Encontré una discusión sobre esto en los foros de Kotlin .

over 4 years ago · Santiago Trujillo Denunciar

0

Esto ocurre debido a la forma ligeramente inesperada en la que se implementa withDefault . El contenedor que produce withDefault no anula getValue() ya que esto es imposible porque getValue() es una función de extensión. Desafortunadamente, lo que tenemos en cambio es un antipatrón OOP clásico: getValue() is una verificación para ver si se está llamando en la interfaz MapWithDefault interna, y solo usa el valor predeterminado si ese es el caso. No veo ninguna forma de que pudieran haber evitado esta situación sin romper el contrato del Mapa.

myGetValue llama a getValue en el delegado subyacente, que es un MapWithDefault , por lo que funciona bien.

getValue en su instancia de MyMap fallará en la verificación interna is MapWithDefault porque MyMap no es un MapWithDefault , aunque su delegado sí lo sea. Los delegados de otros tipos no se propagan hasta la clase que los delega, lo cual tiene sentido. Por ejemplo, si delegamos en un MutableMap, es posible que queramos que la clase se considere solo un mapa de solo lectura.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda