var y val en Kotlin: ¿cuál es la diferencia? Análisis completo
\n\nSi recién estás comenzando tu camino en Kotlin o vienes de otros lenguajes (Java, Python, JavaScript), una de las primeras preguntas que te harás es: ¿por qué se necesitan dos palabras clave para declarar variables? En efecto, ¿para qué complicar si se puede usar una sola? La respuesta está en la filosofía del lenguaje: Kotlin fue creado para hacer el código más seguro, claro y predecible. Y la diferencia entre var y val no es un capricho, sino una herramienta poderosa para la gestión del estado.
Analicemos con ejemplos cuándo usar var y cuándo val, y por qué es importante para tu código.
¿Qué son var y val? Definiciones básicas
\n\nEmpecemos por lo más simple.
\n\n- \n
var(del inglés variable) — variable mutable. Puedes reasignarle un nuevo valor tantas veces como quieras. \n val(del inglés value) — referencia inmutable (solo lectura). Después de la inicialización no puedes cambiar su valor. Es análogo afinalen Java oconsten JavaScript (con matices). \n
Aquí tienes el ejemplo más simple:
\n\nfun main() {\n var x = 10\n x = 20 // OK: var se puede cambiar\n\n val y = 30\n // y = 40 // Error de compilación: val no se puede reasignar\n\n println("x = $x, y = $y")\n}\n\nTodo parece obvio, pero el diablo, como siempre, está en los detalles.
\n\nLa principal diferencia: mutabilidad de la referencia vs mutabilidad del objeto
\n\nAquí suele haber confusión. val garantiza que la referencia al objeto no cambiará, pero no garantiza la inmutabilidad del objeto en sí.
Analicemos con un ejemplo de lista:
\n\nfun main() {\n val numbers = mutableListOf(1, 2, 3)\n // numbers = mutableListOf(4, 5, 6) // Error: val no se puede reasignar\n\n numbers.add(4) // ¡Pero esto sí se puede! Cambiamos el contenido del objeto\n numbers[0] = 100 // Y esto también se puede\n\n println(numbers) // [100, 2, 3, 4]\n}\n\nObserva: declaramos numbers como val, pero agregamos y modificamos elementos sin problema. ¿Por qué? Porque val protege solo la referencia en sí (la variable numbers), no el objeto al que apunta.
Si deseas una inmutabilidad total, debes usar colecciones inmutables (listOf, mapOf, setOf) y val al mismo tiempo.
fun main() {\n val immutableNumbers = listOf(1, 2, 3)\n // immutableNumbers.add(4) // Error: listOf devuelve una lista inmutable\n // immutableNumbers[0] = 100 // Error\n}\n\nEste es un punto importante que suele preguntarse en entrevistas. Recuerda: val ≠ objeto inmutable.
\n\n¿Cuándo usar var y cuándo usar val?
\n\nLa regla de oro de Kotlin: usa val siempre que sea posible, y var solo cuando sea realmente necesario. ¿Por qué?
- \n
- Seguridad. Cuantas menos variables mutables, menos posibilidades de cambiar accidentalmente un valor en un lugar inesperado. Esto es especialmente importante en programación multihilo. \n
- Legibilidad. Cuando ves
val, sabes de inmediato que el valor no cambiará. Esto simplifica la comprensión del código. \n - Estilo funcional. Kotlin fomenta la programación funcional, donde la inmutabilidad es uno de los principios clave. \n
Aquí tienes un ejemplo donde var está justificado:
fun main() {\n var counter = 0\n while (counter < 10) {\n println("Counter: $counter")\n counter++ // El contador debe cambiar\n }\n}\n\nY aquí un ejemplo donde var es una mala práctica y se puede re