Kotlin 1.5.0 : Las 5 novedades que puedes empezar a usar hoy

Kotlin 1.5.0 ya está aquí, y como siempre trae una serie de novedades que te van a interesar muchísimo.
Cabe destacar que a partir de ahora, de acuerdo las nuevas versiones de Kotlin se lanzarán cada 6 meses, independientemente de las nuevas funcionalidades que incluyan.
De esa forma, no se bloquea la salida de funcionalidades porque haya una que no termine de estar lista. Si no lo está para la fecha de lanzamiento, se pospondrá para la siguiente.
Kotlin 1.5.0 llega en mayo de 2021, por lo tanto podemos esperar Kotlin 1.6 para noviembre de 2021.
Estas son las novedades principales de la nueva versión:
1. JVM Records
Si te dedicas al desarrollo de Android, esta funcionalidad no te afecta mucho. En la versión de 16 de Java se ha incluido una funcionalidad similar a las data classes de Kotlin que se llama Record classes.
Para que desde código Java las data classes se puedan usar como records, solo hace falta incluir la anotación @JvmRecord
:
@JvmRecord
data class Person(val name: String, val age: Int)
2. Sealed Interfaces y mejoras en las Sealed Classes
Gracias a las sealed classes, tenemos la opción de que en tiempo de compilación el compilador sepa cuántas subclases tiene una clase.
Esto es un muy potente, porque hace que el compilador nos ayude a comprobar si estamos cubriendo todos los casos. Siempre los he comparado con los enums, pero con superpoderes.
Pero las sealed classes tienen un problema: son clases.
Independientemente de que tengan código o no, nos obligan a usar una clase, y por tanto una subclase no puede implementar dos sealed clases distintas.
Sealed interfaces
Con las sealed interfaces esto ya no ocurre. Una misma clase puede implementar varias sealed interfaces, y además no se nos obliga a crear una clase que no va a tener ningún estado.
Para crearlas, es tan sencillo como usar la palabra reservada sealed
:
sealed interface Error
class GenericError(val message: String): Error
class HttpError(val errorCode: Int): Error
Luego ya se pueden usar en bloque when
exhaustivo sin necesidad de añadir else
:
val res = when (error) {
is GenericError -> TODO()
is HttpError -> TODO()
}
Las sealed classes e interfaces pueden estar en cualquier fichero
Hasta esta versión de Kotlin, se obligaba a que todas las subclasses de las sealed classes estuvieran en el mismo fichero.
Ahora se permite que estén en la misma unidad de compilación. Por ejemplo, para la creación de una librería, esto implica que nadie podría crear subclases de una sealed class desde fuera de la librería.
3. Inline Classes
Estas clases son un poco especiales. A nivel de Kotlin se comportan como clases, pero a nivel de compilación lo hacen como valores o variables.
Esto hace que podamos dar semántica a nuestro código evitando la complejidad añadida a la compilación.
Si por ejemplo tienes un String
que representa una contraseña, podrías querer modelarlo así:
class Password(val s: String)
Esto obliga a que un tipo simple como String genere una clase, lo que implica un overhead extra simplemente porque queremos hacer que nuestro código sea más legible.
Kotlin nos da una nueva opción con las inline classes
:
@JvmInline
value class Password(val s: String)
Esto hará que a nivel de bytecode la clase Password
realmente no exista, sino que donde se está utilizando la clase se sustituya por String del valor que se pasa por el constructor.
La anotación @JvmInline
es obligatoria para que el compilador haga lo que tiene que hacer.
4. Enteros sin signo (Librería estándar)
Se han añadido nuevas funcionalidades a la librería, y otras han pasado de experimental a estable.
Casi todo son pequeños cambios que tampoco merece la pena mencionar, pero lo que sí que llega a estable son los tipos numéricos sin signo y todas las operaciones relacionadas con ellos.
Ahora si quieres usar por ejemplo un entero sin signo, en vez de utilizar Int
, y restringir sus valores mediante código, puedes usar UInt y deja que el compilador te ayude.
Para definir un literal sin signo, hay que añadir una u
tras el valor:
val x: UInt = 0u
5. El nuevo backend IR de Kotlin para la JVM ya es estable
Y será el que se use por defecto con Kotlin 1.5.0.
Cuando se crearon los primeros compiladores de Kotlin, primero el de JVM y luego para JavaScript, ambos compiladores eran totalmente independientes y no compartían mucho código.
Sin embargo, con la llegada de Kotlin/Native, empezaron a trabajar en un nuevo compilador. Se llama IR por Intermediate Representation.
Esto permite que todos los compiladores generen una representación intermedia de la compilación final (el equivalente a un bytecode de Java), que lo genera lo que llaman el “frontend” de compilación.
Luego cada backend específico convierte esa reprendentación intermedia al resultado que necesite: en el caso de JVM a bytecode, y en el de JS a JavaScript.
Gracias a esto, consiguen compartir código por un lado, y optimizar los procesos de compilación por otro.
El backend de JVM ha sido reescrito para trabajar con este nuevo compilador y ya se usa por defecto.
El backend de JS por su lado ha sido promocionado a Beta.
Y un montón de pequeños detalles más
Estas son las novedades más destacadas, pero como siempre, hay un montón de pequeñas optimizaciones para cada uno de los entornos que mejoran compatibilidades con los lenguajes con los que interopera, optimiza tiempos de compilación, mejora las herramientas…
Esta nueva versión de Kotlin confirma otro salto de calidad con novedades que ayudan a que trabajar con este lenguaje sea cada vez más sencillo y eficiente.
Cómo conseguir la localización amplia en Android
Cómo pedir permisos en Jetpack Compose