En Kotlin, como en todo lenguaje, tenemos operadores predefinidos para realizar ciertas operaciones.

Los más típicos son la suma (+), resta (-), multiplicación (*) o división (/), pero hay unos cuantos más.

En algunos lenguajes, como en Java, estos operadores están limitados a ciertos tipos de datos, y no tenemos forma de hacer que otros tipos los utilicen.

Hay otros lenguajes como Scala en los que nos podemos inventar cualquier tipo de operador que se nos ocurra, ya que los nombres de las funciones aceptan cualquier símbolo.

En Kotlin se toma una solución intermedia: hay una serie de operadores predefinidos, pero los podemos sobrecargar para cualquier tipo de datos.

Este artículo forma parte de una serie de 30 con motivo del lanzamiento del curso presencial Kotlin para Desarrolladores Android que impartiré en breve. ¡No te lo pierdas!

kotlin-desarrolladores-android

Sobrecarga de operadores en Kotlin

Como hablábamos, en Kotlin se pueden sobrecargar cierto número de operadores, implementando la función correspondiente en nuestra clase. Esa función debe ser marcada con la palabra reservada operator.

Los operadores son básicamente los siguientes:

Operadores Unarios

+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a++ a.inc()
a– a.dec()

Operadores Binarios

a + b a.plus(b)
a – b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.mod(b)
a..b a.rangeTo(b)
a in b b.contains(a)
a !in b !b.contains(a)
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a.timesAssign(b)
a /= b a.divAssign(b)
a %= b a.modAssign(b)

Operadores tipo array

a[i] a.get(i)
a[i, j] a.get(i, j)
a[i_1, …, i_n] a.get(i_1, …, i_n)
a[i] = b a.set(i, b)
a[i, j] = b a.set(i, j, b)
a[i_1, …, i_n] = b a.set(i_1, …, i_n, b)

Operación Equals

a == b a?.equals(b) ?: b === null
a != b !(a?.equals(b) ?: b === null)

Las operaciones equals son un poco diferentes, porque usan una traducción más compleja para hacer un chequeo correcto, y porque esperan una especificación exacta de la función, y no sólo un nombre específico para la misma. La función debe ser implementada exactamente así:

Invocación de funciones

a(i) a.invoke(i)
a(i, j) a.invoke(i, j)
a(i_1, …, i_n) a.invoke(i_1, …, i_n)

Un ejemplo

Imagina que tienes un modelo de datos que son compañías, cada una de las cuales tiene un listado de empleados.

Podrías utilizar el operador get para acceder a las posiciones mediante corchetes. La implementación es muy sencilla:

Y así es como podrías usarlo:

Pero podrías ir más, allá, y usar el id para recuperar el valor, implementando la función así:

Conclusión

Los operadores nos pueden ayudar a dar mayor legibilidad utilizando símbolos comunes para operaciones conocidas.

Hay que tener cuidado con no utilizarlos en situaciones en las que pueda llevar a confusión a las personas que lo lean, pero se pueden convertir en una herramienta realmente interesante.

Si todavía no lo has hecho, te recomiendo que te unas al curso de Kotlin cuanto antes si no quieres quedarte sin plaza.