Kotlin
A concise multiplatform language developed by JetBrains
Lanzamiento de Kotlin 1.5.0-RC: cambios en las bibliotecas estándar y de prueba
Kotlin 1.5.0-RC ya está disponible con todas las funcionalidades planificadas para 1.5.0. ¡Eche un vistazo a todas las novedades del próximo lanzamiento! Nuevas funcionalidades de lenguaje, actualizaciones de stdlib, una biblioteca de pruebas mejorada y muchos otros cambios están recibiendo los toques finales. Los únicos cambios adicionales antes del lanzamiento serán los arreglos.
Pruebe las modernas API de Kotlin para sus proyectos con 1.5.0-RC ¡y ayúdenos a mejorar esta versión! Infórmenos acerca de cualquier incidencia que encuentre en nuestro sistema de seguimiento de incidencias, YouTrack.
En este artículo le describiremos los cambios en las bibliotecas estándar y de prueba de Kotlin en 1.5.0-RC:
- Tipos enteros no firmados estables
- Extensiones para java.nio.file.Path
- Mejoras en las cadenas y API de caracteres
- Cambios en la API Duration
- Nuevas operaciones matemáticas para aritmética modular
- Nuevas funciones de colección
- Cambios en bibliotecas de pruebas
¡Encontrará todos los detalles a continuación!
Tipos enteros no firmados estables
La biblioteca estándar incluye la API para enteros no firmados que resulta práctica para operaciones con enteros no negativos. Incluye:
- Tipos numéricos no firmados:
UInt
,ULong
,UByte
,UShort
, y las funciones relacionadas, como conversiones. - Tipos agregados: vectores, intervalos y progresiones de enteros no firmados:
UIntArray
,UIntRange
y contenedores similares para otros tipos.
Los tipos enteros no firmados han estado disponibles en Beta desde Kotlin 1.3. Ahora estamos clasificando los tipos de enteros no firmados y las operaciones como estables, para que estén disponibles sin opt-in y sea seguro utilizarlos en proyectos reales.
Las nuevas API estables son:
- Tipos enteros no firmados
- Intervalos y progresiones de tipos enteros no firmados
- Funciones que operan con tipo enteros no firmados
Los vectores de enteros no firmados se quedan en Beta. Y también los varargs enteros no firmados respaldados por vectores. Si desea utilizarlos en su código, puede hacer opt-in con la anotación @ExperimentalUnsignedTypes
.
Más información acerca de enteros no firmados en Kotlin.
Extensiones para la API java.nio.file.Path
Kotlin ahora ofrece un modo de utilizar la moderna IO Java sin bloqueo en un estilo idiomático de Kotlin listo para usar a través de las funciones de extensión para java.nio.file.Path
.
Este es un pequeño ejemplo:
Estas extensiones se introdujeron como funcionalidad experimental en Kotlin 1.4.20, y ahora están disponibles sin opt-in. Eche un vistazo al paquete kotlin.io.path
para ver la lista de funciones que puede utilizar.
Las extensiones existentes para File API siguen estando disponibles, para que pueda escoger la API que más le guste.
API independiente local para mayúsculas y minúsculas
Muchos de ustedes ya están familiarizados con las funciones stdlib para cambiar entre mayúsculas y minúsculas las cadenas y caracteres: toUpperCase()
, toLowerCase()
, toTitleCase()
. En general, funcionan bien, pero pueden ser un dolor de cabeza a la hora de tratar con diferentes configuraciones regionales en las plataformas: son sensibles a la configuración regional, lo que supone que su resultado puede diferir dependiendo de dicha configuración. Por ejemplo, ¿qué obtiene con ”Kotlin”.toUpperCase()
? “Obviamente KOTLIN
”, dirá. Pero en la configuración turca, la i
mayúscula es İ
, de modo que el resultado es diferente: KOTLİN
.
Ahora hay una nueva API independiente de la configuración local para cambiar entre mayúsculas y minúsculas en cadenas y caracteres: extensiones uppercase()
, lowercase()
, titlecase()
y sus contrapartes *Char()
. Puede que ya haya probado su vista previa en 1.4.30.
Las nuevas funciones operan del mismo modo independientemente de la configuración local de la plataforma. Solo tiene que llamar a estas funciones y dejar el resto a la stdlib.
Las nuevas funciones operan del mismo modo independientemente de la configuración local de la plataforma. Solo tiene que llamar a estas funciones y dejar el resto a la stdlib.
En la JVM puede cambiar las mayúsculas y minúsculas teniendo en cuenta la configuración regional llamando a las nuevas funciones con la configuración actual como argumento
Las nuevas funciones sustituirán por completo a las antiguas, que pronto quedarán obsoletas.
Conversiones claras de caracter a código y de caracter a dígito
La operación de obtener un código UTF-16 de un caracter, la función toInt()
, era una dificultad común, porque parece muy similar a String.toInt()
en cadenas de un dígito que produzcan un Int
presentado por este dígito.
Además, no había una función común que devolviera el valor numérico 4
para Char
'4'
.
Para resolver estas incidencias, ahora existe una serie de nuevas funciones para la conversión entre caracteres y sus códigos enteros y valores numéricos:
Char(code)
yChar.code
convierten entre un caracter y su código.Char.digitToInt(radix: Int)
y su versión*OrNull
crean un entero a partir de un dígito en la base especificada.Int.digitToChar(radix: Int)
crea un caracter a partir de un dígito que representa un entero en la base especificada.
Estas funciones tienen nombres claros que hacen que el código sea más legible:
Las nuevas funciones han estado disponibles desde Kotlin 1.4.30 en el modo de vista previa y ahora son estables. Las antiguas funciones para la conversión de caracter a número (Char.toInt()
y funciones similares para otros tipos numéricos) y conversión de número a caracter (Long.toChar()
y similares excepto Int.toChar()
) ahora están obsoletas.
API de caracteres multiplataforma extendida
Continuaremos ampliando la parte multiplataforma de la biblioteca estándar para ofrecer todas sus capacidades al código común del proyecto multiplataforma.
Ahora hemos puesto a su disposición una gran cantidad de funciones Char
en todas las plataformas y en el código común. Estas funciones son:
Char.isDigit()
,Char.isLetter()
,Char.isLetterOrDigit()
que comprueban si un caracter es una letra o un dígito.Char.isLowerCase()
,Char.isUpperCase()
,Char.isTitleCase()
que comprueban si un caracter es mayúscula o minúscula.Char.isDefined()
que comprueba si un caracter tiene una categoría general Unicode distinta deCn
(undefined).Char.isISOControl()
que comprueba si un caracter es un caracter de control ISO, que cuenta con un código en los intervalos\u0000
..\u001F
o\u007F
..\u009F
.
La propiedad Char.category
y su clase CharCategory
, que indica la categoría general de un caracter según Unicode, está ahora disponilble en proyectos multiplataforma.
Versiones estrictas de String?.toBoolean()
La función de Kotlin String?.toBoolean()
se usa en gran medida para crear valores booleanos a partir de cadenas. Su funcionaomiento es muy sencillo: es true
en una cadena "true" independientemente de si es mayúscula y minúscula y false
en todas las demás cadenas, incluyendo null
.
Aunque este comportamiento parece natural, puede ocultar situaciones potencialmente erróneas. Convierta lo que convierta con esta función, obtendrá una booleana incluso si la cadena tiene un valor inesperado.
Dispone de nuevas versiones estrictas sensibles a las mayúsculas de String?.toBoolean() para evitar dichos errores:
String.toBooleanStrict()
lanza una excepción para todas las entradas excepto literales “true” y “false”.String.toBooleanStrictOrNull()
devuelve null para todas las entradas excepto literales “true” y “false”.
Cambios en la API Duration
La API de medición de tiempo y duración experimental ha estado disponible dentro de la stdlib desde la versión 1.3.50. Ofrece una API para la medición precisa de los intervalos de tiempo.
Una de las clases clave de esta API es Duration
. Representa la cantidad de tiempo entre dos momentos temporales. En 1.5.0, Duration
se somete a cambios significativos tanto en la API como en la representación interna.
Duration
ahora utiliza un valor Long
para la representación interna en lugar de Double
. El intervalo de los valores Long
permite representar más de cien años con precisión de nanosegundos o cien millones de años con precisión de milisegundos. No obstante, las duraciones de subnanosegundos anteriormente compatibles ya no están disponibles.
También vamos a introducir nuevas propiedades para recuperar una duración como valor Long
. Están disponibles para varias unidades de tiempo: Duration.inWholeMinutes
, Duration.inWholeSeconds
y otras. Estas funciones sustituirán a las propiedades basadas en Double
como Duration.inMinutes
.
Otro cambio es una serie de nuevas funciones de fábrica para crear instancias de Duration
a partir de valores enteros. Se definen directamente en el tipo Duration
y sustituyen a las antiguas propiedades de extensión de tipos numéricos como Int.seconds
.
Dados estos importantes cambios, toda la API de duración y medición del tiempo sigue siendo experimental en 1.5.0 y requiere un opt-in con la anotación @ExperimentalTime
.
Pruebe la nueva versión y envíenos su feedback a través de nuestro sistema de seguimiento de incidencias YouTrack.
Operaciones matemáticas: floored division y el mod operator
En Kotlin, el símbolo de división (/
) en números enteros representa la división truncada, que omite la parte fraccionada del resultado. En la aritmética modular, también existe una alternativa: floored division, que redondea el resultado (hacia el número entero justo por debajo), lo cual da un resultado diferente en números negativos.
Anteriormente, la floored division requería una función personalizada como:
En 1.5.0-RC, representamos la función floorDiv()
que realiza la floored division en números enteros.
En 1.5.0, introducimos la nueva función mod()
. Ahora funciona exactamente como su nombre sugiere: devuelve el módulo recordatorio de la floored division.
Es distinto del rem()
(u operador %
) de Kotlin. El módulo es la diferencia entre a
y a.floorDiv(b) * b
. Un módulo no cero siempre tiene el mismo símbolo que b
, mientras que a % b
puede tener uno distinto. Esto puede resultar útil, por ejemplo, al implementar listas cíclicas:
Colecciones: firstNotNullOf() y firstNotNullOfOrNull()
La API de colecciones Kotlin abarca toda una gama de operaciones populares en colecciones con funciones integradas. Para casos no habituales, normalmente se combinan llamadas de estas funciones. Funciona, pero no siempre queda muy elegante y puede causar sobrecostes.
Por ejemplo, para obtener el primer resultado no null de una función de selector en los elementos de la colección, podría llamar a mapNotNull()
y first()
. En 1.5.0, puede hacerlo con una sola llamada de una nueva función firstNotNullOf()
. Junto con firstNotNullOf()
, añadimos su contraparte *orNull()
que produce null si no hay un valor que devolver.
Este es un ejemplo de cómo puede abreviar su código.
Imagine que tiene una clase con una propiedad que acepta valores null y necesita su primer valor no null de una lista de las instancias de clase.
You can implement this by iterating the collection and checking if a property is not null:
Otro modo es utilizar las funciones previamente existentes mapNotNull()
y firstOrNull()
. Tenga en cuenta que mapNotNull()
crea una colección inmediata, que requiere memoria adicional, especialmente para grandes colecciones. Así pues, ahí también podría necesitarse una transformación en secuencia.
Y esta es su apariencia con la nueva función:
Cambios en bibliotecas de pruebas
No habíamos realizado grandes actualizaciones en la biblioteca de pruebas de Kotlin kotlin-test
en varias versiones, pero ahora vamos a incluir algunos esperados cambios. Con 1.5.0-RC, puede probar varias nuevas funcionalidades:
- Dependencia individual de
kotlin-test
en proyectos multiplataforma. - Selección automática de un marco de pruebas para conjuntos de fuentes Kotlin/JVM.
- Actualizaciones en la función de aserción.
Dependencia de kotlin-test en proyectos multiplataforma
Vamos a continuar nuestro desarrollo del proceso de configuración para proyectos multiplataforma. En 1.5.0, hemos facilitado la configuración de una dependencia en kotlin-test
para todos los conjuntos de fuentes.
Ahora, la dependencia de kotlin-test
en el conjunto de fuentes de prueba comunes es el único que tiene que añadir. El complemento Gradle inferirá la dependencia de plataforma correspondiente para otros conjuntos de fuentes:
kotlin-test-junit
para conjuntos de fuentes JVM. También puede cambiar akotlin-test-junit-5
okotlin-test-testng
si las habilita explícitamente (siga leyendo para saber cómo).kotlin-test-js
para conjuntos de fuentes Kotlin/JS.kotlin-test-common
ykotlin-test-annotations-common
para conjuntos de fuentes comunes.- Sin artefacto extra para conjuntos de fuentes Kotlin/Native, porque Kotlin/Native ofrece implementaciones integradas de la API
kotlin-test
.
Selección automática de un marco de pruebas para conjuntos de fuentes Kotlin/JVM
Cuando especifica la dependencia kotlin-test
en el conjunto de fuentes de prueba comunes tal y como se ha descrito anteriormente, los conjuntos de fuentes JVM reciben automáticamente la dependencia en JUnit 4. ¡Y ya está! ¡Puede escribir y ejecutar pruebas inmediatamente!
Así se ve en el DSL Groovy:
Y en el DSL de Kotlin es:
También puede cambiar a JUnit 5 o TestNG simplemente llamando a una función en la tarea de prueba useJUnitPlatform()
o useTestNG()
.
Lo mismo sucede en proyectos solo JVM cuando añade la dependencia kotlin-test
.
Actualizaciones en las funciones de aserción
Para 1.5.0, hemos preparado varias nuevas funciones de aserción, junto con mejoras en las ya existentes.
En primer lugar, echemos un vistazo rápido a las nuevas funciones:
assertIs<T>()
yassertIsNot<T>()
comprueban el tipo de valor.assertContentEquals()
compara el contenido del contenedor en cuanto a vectores, secuencias y cualquierIterable
. Más específicamente, comprueba siexpected
yactual
contienen los mismos elementos en el mismo orden.assertEquals()
yassertNotEquals()
paraDouble
yFloat
cuentan con nuevas sobrecargas con un tercer parámetro: precisión.assertContains()
comprueba la presencia de un elemento en cualquier objeto con el operadorcontains()
definido: vector, lista, intervalo, etc.
Este es un breve ejemplo que muestra el uso de estas funciones:
Con respecto a las funciones de aserción existentes: ahora se puede llamar a funciones de suspensión dentro de lambda pasadas a assertTrue()
, assertFalse()
y expect()
porque estas funciones están ahora alineadas.
Pruebe todas las funcionalidades de Kotlin 1.5.0
¡Use estas modernas API de Kotlin en sus proyectos reales con 1.5.0-RC!
En IntelliJ IDEA o Android Studio, instale el complemento Kotlin 1.5.0-RC. Descubra cómo obtener las versiones anticipadas de los complementos.
Cree sus proyectos existentes con 1.5.0-RC para comprobar cómo funcionarán con 1.5.0. Con la nueva configuración simplificada para lanzamientos en vista previa, solo tiene que pasarse a la versión de Kotlin 1.5.0-RC
y ajustar las versiones de dependencia si fuese necesario.
Como siempre, puede probar la última versión online en el Kotlin Playground.
Compatibilidad
Como en todas las versiones, algunos ciclos de entrada en desuso de cambios anunciados previamente llegarán a su fin con Kotlin 1.5.0. El comité del lenguaje ha revisado detenidamente todos estos casos y los ha incluido en la Guía de compatibilidad de Kotlin 1.5. También puede consultar dichos cambios en YouTrack.
Notas sobre el lanzamiento
Ahora que ya tenemos la candidata para el lanzamiento de Kotlin 1.5, ha llegado el momento de que empiece a compilar y publicitar. A diferencia de con versiones anteriores, está garantizado que los binarios creados con Kotlin 1.5-RC sean compatibles con Kotlin 1.5.0-RC.
Envíenos sus comentarios
¡Esta es su última oportunidad de participar en el siguiente lanzamiento de funcionalidades! Comparta con nosotros cualquier incidencia que encuentre en el sistema de seguimiento de incidencias. ¡Mejore Kotlin 1.5.0 para usted y para la comunidad!