Principales errores de los desarrolladores principiantes de Kotlin: de la A a la Z

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Por qué incluso los desarrolladores inteligentes tropiezan con Kotlin?

\n\n

Kotlin es un lenguaje elegante y potente que ha conquistado los corazones de millones de desarrolladores. Pero su concisión y flexibilidad esconden trampas, especialmente para los principiantes que vienen de Java u otros lenguajes. Muchos piensan que como Kotlin es «más comprensible» que Java, habrá menos errores. En la práctica ocurre lo contrario: la falta de comprensión de la filosofía del lenguaje provoca bugs difíciles de detectar.

\n\n

En este artículo analizaremos los principales errores de los desarrolladores principiantes de Kotlin, desde la simple ignorancia de null safety hasta el uso incorrecto de las corrutinas. Cada error se ilustrará con un ejemplo de código y un consejo práctico sobre cómo evitarlo.

\n\n

1. Null Safety: cuándo «?» salva y cuándo no

\n\n

1.1. Ignorar los tipos nullable

\n

El error más común es usar !! (not-null assertion) donde se podrían usar llamadas seguras. Los principiantes suelen escribir:

\n\n
fun printLength(str: String?) {\n    println(str!!.length) // Lanzará NPE si str == null\n}
\n\n

El enfoque correcto es usar ?.let o el operador Elvis ?::

\n\n
fun printLength(str: String?) {\n    str?.let { println(it.length) } ?: println("Cadena null")\n}
\n\n

1.2. Olvidar el Smart Cast

\n

Kotlin convierte tipos automáticamente después de una comprobación de null, pero los principiantes no lo notan:

\n\n
fun process(value: Any?) {\n    if (value is String) {\n        // value ya es String, ¡no necesita casteo!\n        println(value.length) // Funciona sin (value as String).length\n    }\n}
\n\n

Consejo: Confíen en el compilador. Usen !! solo si están 100% seguros de que el valor no es null y están preparados para un fallo si se equivocan.

\n\n

2. Sealed Class y When: trampas de la exhaustividad

\n\n

2.1. Usar la rama else con sealed class

\n

Las sealed class están diseñadas para que el compilador verifique si se han manejado todas las variantes. Pero los principiantes suelen añadir else, matando toda la magia:

\n\n
sealed class Result {\n    data class Success(val data: String) : Result()\n    data class Error(val message: String) : Result()\n}\n\nfun handleResult(result: Result) {\n    when (result) {\n        is Result.Success -> println(result.data)\n        is Result.Error -> println(result.message)\n        else -> {} // ¡Error! Si se añade una nueva subclase, el compilador no avisará\n    }\n}
\n\n

Lo correcto es no usar else:

\n\n
fun handleResult(result: Result) {\n    when (result) {\n        is Result.Success -> println(result.data)\n        is Result.Error -> println(result.message)\n    } // El compilador dará error si no se cubren todas las ramas\n}
\n\n

2.2. Confundir sealed class con enum

\n

Los principiantes suelen elegir enum donde se necesita sealed class. Recuerden: enum es para un conjunto finito de constantes, sealed class es para una jerarquía con diferentes datos en cada subclase.

\n\n

3. Scope Functions: apply, let, run, with, also — cómo no confundirse

\n\n

3.1. Mezclar el contexto: this vs it

\n

La confusión más común es cuando un principiante usa apply (contexto — this) para operaciones donde se necesita let (contexto — it):

\n\n
data class User(var name: String, var age: Int)\n\nfun initUser(): User {\n    return User("Anónimo", 0).apply {\n        // this — es User\n        name = "Iván"\n        age = 25\n    }\n}\n\nfun printUserInfo(user: User?) {\n    user?.let { \n        // it — es user\n        println("Nombre: ${it.name}, Edad: ${it.age}")\n    }\n}
\n\n

3.2. Cadenas de scope functions sin sentido

\n

A los principiantes les gusta escribir cadenas como:

\n\n
list?.let { it.filter { it > 5 }.also { println(it) } }

                
                

Blogs

Book Recommendations