{"id":138784,"date":"2021-04-27T05:06:45","date_gmt":"2021-04-27T04:06:45","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=kotlin&#038;p=138784"},"modified":"2021-04-27T05:06:45","modified_gmt":"2021-04-27T04:06:45","slug":"lanzamiento-de-kotlin-1-5-0-rc-cambios-en-las-bibliotecas-estandar-y-de-prueba","status":"publish","type":"kotlin","link":"https:\/\/blog.jetbrains.com\/es\/kotlin\/2021\/04\/lanzamiento-de-kotlin-1-5-0-rc-cambios-en-las-bibliotecas-estandar-y-de-prueba\/","title":{"rendered":"Lanzamiento de Kotlin 1.5.0-RC: cambios en las bibliotecas est\u00e1ndar y de prueba"},"content":{"rendered":"<p>Kotlin 1.5.0-RC ya est\u00e1 disponible con todas las funcionalidades planificadas para 1.5.0. \u00a1Eche un vistazo a todas las novedades del pr\u00f3ximo lanzamiento! Nuevas funcionalidades de lenguaje, actualizaciones de stdlib, una biblioteca de pruebas mejorada y muchos otros cambios est\u00e1n recibiendo los toques finales. Los \u00fanicos cambios adicionales antes del lanzamiento ser\u00e1n los arreglos.<\/p>\n<\/p>\n<p>Pruebe las modernas API de Kotlin para sus proyectos con 1.5.0-RC \u00a1y ay\u00fadenos a mejorar esta versi\u00f3n! Inf\u00f3rmenos acerca de cualquier incidencia que encuentre en nuestro sistema de seguimiento de incidencias, <a href=\"https:\/\/kotl.in\/issue\" target=\"_blank\" rel=\"noopener\">YouTrack<\/a>.<\/p>\n<p align=\"center\"><a class=\"jb-download-button\" title=\"Instalar\" href=\"https:\/\/kotlinlang.org\/docs\/install-eap-plugin.html\" target=\"_blank\" rel=\"noopener\">Instale 1.5.0-RC<\/a><\/p>\n<p>En este art\u00edculo le describiremos los cambios en las bibliotecas est\u00e1ndar y de prueba de Kotlin en 1.5.0-RC:<\/p>\n<ul>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#stable-unsigned-integer-types\">Tipos enteros no firmados estables<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#extensions-for-java-nio-path\">Extensiones para java.nio.file.Path<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#locale-agnostic-upper-lowercase\">Mejoras en las cadenas y API de caracteres<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#duration-api-changes\">Cambios en la API Duration<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#math-operations-floordiv-mod\">Nuevas operaciones matem\u00e1ticas para aritm\u00e9tica modular<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#collections-firstnotnullof\">Nuevas funciones de colecci\u00f3n<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/04\/kotlin-1-5-0-rc-released\/#test-library-changes\">Cambios en bibliotecas de pruebas<\/a><\/li>\n<\/ul>\n<p>\u00a1Encontrar\u00e1 todos los detalles a continuaci\u00f3n!<\/p>\n<p><a name = \"stable-unsigned-integer-types\"><\/a><\/p>\n<h2>Tipos enteros no firmados estables<\/h2>\n<p>La biblioteca est\u00e1ndar incluye la API para enteros no firmados que resulta pr\u00e1ctica para operaciones con enteros no negativos. Incluye:<\/p>\n<ul>\n<li>Tipos num\u00e9ricos no firmados: <code>UInt<\/code>, <code>ULong<\/code>, <code>UByte<\/code>, <code>UShort<\/code>, y las funciones relacionadas, como conversiones.<\/li>\n<li>Tipos agregados: vectores, intervalos y progresiones de enteros no firmados: <code>UIntArray<\/code>, <code>UIntRange<\/code> y contenedores similares para otros tipos.<\/li>\n<\/ul>\n<p>Los tipos enteros no firmados han estado disponibles en Beta desde <a href=\"https:\/\/kotlinlang.org\/docs\/whatsnew13.html#unsigned-integers\" target=\"_blank\" rel=\"noopener\">Kotlin 1.3<\/a>. Ahora estamos clasificando los tipos de enteros no firmados y las operaciones como estables, para que est\u00e9n disponibles sin opt-in y sea seguro utilizarlos en proyectos reales.<\/p>\n<p>Las nuevas API estables son:<\/p>\n<ul>\n<li>Tipos enteros no firmados<\/li>\n<li>Intervalos y progresiones de tipos enteros no firmados<\/li>\n<li>Funciones que operan con tipo enteros no firmados<\/li>\n<\/ul>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    val zero = 0U \/\/ Define unsigned numbers with literal suffixes\n    val ten = 10.toUInt() \/\/ or by converting non-negative signed numbers\n    \/\/val minusOne: UInt = -1U \/\/ Error: unary minus is not defined\n    val range: UIntRange = zero..ten \/\/ Separate types for ranges and progressions\n\n    for (i in range) print(i)\n    println()\n    println(&quot;UInt covers the range from ${UInt.MIN_VALUE} to ${UInt.MAX_VALUE}&quot;) \/\/ UInt covers the range from 0 to 4294967295\n\/\/sampleEnd\n}\n<\/pre>\n<p>Los vectores de enteros no firmados se quedan en Beta. Y tambi\u00e9n los <a href=\"https:\/\/kotlinlang.org\/docs\/functions.html#variable-number-of-arguments-varargs\" target=\"_blank\" rel=\"noopener\">varargs<\/a> enteros no firmados respaldados por vectores. Si desea utilizarlos en su c\u00f3digo, puede hacer opt-in con la anotaci\u00f3n <code>@ExperimentalUnsignedTypes<\/code>.<\/p>\n<p>M\u00e1s informaci\u00f3n acerca de <a href=\"https:\/\/kotlinlang.org\/docs\/basic-types.html#unsigned-integers\" target=\"_blank\" rel=\"noopener\">enteros no firmados en Kotlin<\/a>.<\/p>\n<p><a name = \"extensions-for-java-nio-path\"><\/a><\/p>\n<h2>Extensiones para la API java.nio.file.Path<\/h2>\n<p>Kotlin ahora ofrece un modo de utilizar la moderna <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/nio\/package-summary.html\" target=\"_blank\" rel=\"noopener\">IO Java sin bloqueo<\/a> en un estilo idiom\u00e1tico de Kotlin listo para usar a trav\u00e9s de las funciones de extensi\u00f3n para <a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/nio\/file\/Path.html\" target=\"_blank\" rel=\"noopener\"><code>java.nio.file.Path<\/code><\/a>.<\/p>\n<p>Este es un peque\u00f1o ejemplo:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nimport kotlin.io.path.*\nimport java.nio.file.Path\n\nfun main() {\n    \/\/ construct path with the div (\/) operator\n    val baseDir = Path(&quot;\/base&quot;)\n    val subDir = baseDir \/ &quot;subdirectory&quot;\n\n    \/\/ list files in a directory\n    val kotlinFiles = Path(&quot;\/home\/user&quot;).listDirectoryEntries(&quot;*.kt&quot;)\n    \/\/ count lines in all kotlin files\n    val totalLines = kotlinFiles.sumOf { file -&gt; file.useLines { lines -&gt; lines.count() } }\n}\n<\/pre>\n<p>Estas extensiones se introdujeron como funcionalidad experimental <a href=\"https:\/\/kotlinlang.org\/docs\/whatsnew1420.html#extensions-for-java-nio-file-path\" target=\"_blank\" rel=\"noopener\">en Kotlin 1.4.20<\/a>, y ahora est\u00e1n disponibles sin opt-in. Eche un vistazo al paquete <a href=\"https:\/\/kotlinlang.org\/api\/latest\/jvm\/stdlib\/kotlin.io.path\/\" target=\"_blank\" rel=\"noopener\"><code>kotlin.io.path<\/code><\/a> para ver la lista de funciones que puede utilizar.<\/p>\n<p>Las extensiones existentes para File API siguen estando disponibles, para que pueda escoger la API que m\u00e1s le guste.<\/p>\n<p><a name = \"locale-agnostic-upper-lowercase\"><\/a><\/p>\n<h2>API independiente local para may\u00fasculas y min\u00fasculas<\/h2>\n<p>Muchos de ustedes ya est\u00e1n familiarizados con las funciones stdlib para cambiar entre may\u00fasculas y min\u00fasculas las cadenas y caracteres: <code>toUpperCase()<\/code>, <code>toLowerCase()<\/code>, <code>toTitleCase()<\/code>. 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\u00f3n regional, lo que supone que su resultado puede diferir dependiendo de dicha configuraci\u00f3n. Por ejemplo, \u00bfqu\u00e9 obtiene con <code>\u201dKotlin\u201d.toUpperCase()<\/code>? \u201cObviamente <code>KOTLIN<\/code>\u201d, dir\u00e1. Pero en la configuraci\u00f3n turca, la <code>i<\/code> may\u00fascula es <code>\u0130<\/code>, de modo que el resultado es diferente: <code>KOTL\u0130N<\/code>.<\/p>\n<p>Ahora hay una nueva API independiente de la configuraci\u00f3n local para cambiar entre may\u00fasculas y min\u00fasculas en cadenas y caracteres: extensiones <code>uppercase()<\/code>, <code>lowercase()<\/code>, <code>titlecase()<\/code> y sus contrapartes <code>*Char()<\/code>. Puede que ya haya probado <a href=\"https:\/\/kotlinlang.org\/docs\/whatsnew1430.html#locale-agnostic-api-for-upper-lowercasing-text\" target=\"_blank\" rel=\"noopener\">su vista previa en 1.4.30<\/a>.<\/p>\n<p>Las nuevas funciones operan del mismo modo independientemente de la configuraci\u00f3n local de la plataforma. Solo tiene que llamar a estas funciones y dejar el resto a la stdlib.<\/p>\n<p>Las nuevas funciones operan del mismo modo independientemente de la configuraci\u00f3n local de la plataforma. Solo tiene que llamar a estas funciones y dejar el resto a la stdlib.<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    \/\/ replace the old API\n    println(&quot;Kotlin&quot;.toUpperCase()) \/\/ KOTLIN or KOTL\u0130N or?..\n\n    \/\/ with the new API\n    println(&quot;Kotlin&quot;.uppercase()) \/\/ Always KOTLIN\n\/\/sampleEnd\n}\n<\/pre>\n<p>En la JVM puede cambiar las may\u00fasculas y min\u00fasculas teniendo en cuenta la configuraci\u00f3n regional llamando a las nuevas funciones con la configuraci\u00f3n actual como argumento<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n&quot;Kotlin&quot;.uppercase(Locale.getDefault()) \/\/ Locale-sensitive uppercasing\n<\/pre>\n<p>Las nuevas funciones sustituir\u00e1n por completo a las antiguas, que pronto quedar\u00e1n obsoletas.<\/p>\n<h2>Conversiones claras de caracter a c\u00f3digo y de caracter a d\u00edgito<\/h2>\n<p>La operaci\u00f3n de obtener un c\u00f3digo UTF-16 de un caracter, la funci\u00f3n <code>toInt()<\/code>, era una dificultad com\u00fan, porque parece muy similar a <code>String.toInt()<\/code> en cadenas de un d\u00edgito que produzcan un <code>Int<\/code> presentado por este d\u00edgito.<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n&quot;4&quot;.toInt() \/\/ returns 4\n'4'.toInt() \/\/ returns 52\n<\/pre>\n<p>Adem\u00e1s, no hab\u00eda una funci\u00f3n com\u00fan que devolviera el valor num\u00e9rico <code>4<\/code> para <code>Char<\/code> <code>'4'<\/code>.<\/p>\n<p>Para resolver estas incidencias, ahora existe una serie de nuevas funciones para la conversi\u00f3n entre caracteres y sus c\u00f3digos enteros y valores num\u00e9ricos:<\/p>\n<ul>\n<li><code>Char(code)<\/code> y <code>Char.code<\/code> convierten entre un caracter y su c\u00f3digo.<\/li>\n<li><code>Char.digitToInt(radix: Int)<\/code> y su versi\u00f3n <code>*OrNull<\/code> crean un entero a partir de un d\u00edgito en la base especificada.<\/li>\n<li><code>Int.digitToChar(radix: Int)<\/code> crea un caracter a partir de un d\u00edgito que representa un entero en la base especificada.<\/li>\n<\/ul>\n<p>Estas funciones tienen nombres claros que hacen que el c\u00f3digo sea m\u00e1s legible:<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    val capsK = Char(75) \/\/ \u2018K\u2019\n    val one = '1'.digitToInt(10) \/\/ 1\n    val digitC = 12.digitToChar(16) \/\/ hexadecimal digit \u2018C\u2019\n\n    println(&quot;${capsK}otlin ${one}.5.0-R${digitC}&quot;) \/\/ \u201cKotlin 1.5.0-RC\u201d\n    println(capsK.code) \/\/ 75\n\/\/sampleEnd\n}\n<\/pre>\n<p>Las nuevas funciones <a href=\"https:\/\/kotlinlang.org\/docs\/whatsnew1430.html#clear-char-to-code-and-char-to-digit-conversions\" target=\"_blank\" rel=\"noopener\">han estado disponibles desde Kotlin 1.4.30<\/a> en el modo de vista previa y ahora son estables. Las antiguas funciones para la conversi\u00f3n de caracter a n\u00famero (<code>Char.toInt()<\/code> y funciones similares para otros tipos num\u00e9ricos) y conversi\u00f3n de n\u00famero a caracter (<code>Long.toChar()<\/code> y similares excepto <code>Int.toChar()<\/code>) ahora est\u00e1n obsoletas.<\/p>\n<h2>API de caracteres multiplataforma extendida<\/h2>\n<p>Continuaremos ampliando la parte multiplataforma de la biblioteca est\u00e1ndar para ofrecer todas sus capacidades al c\u00f3digo com\u00fan del proyecto multiplataforma.<\/p>\n<p>Ahora hemos puesto a su disposici\u00f3n una gran cantidad de funciones <code>Char<\/code> en todas las plataformas y en el c\u00f3digo com\u00fan. Estas funciones son:<\/p>\n<ul>\n<li><code>Char.isDigit()<\/code>, <code>Char.isLetter()<\/code>, <code>Char.isLetterOrDigit()<\/code> que comprueban si un caracter es una letra o un d\u00edgito.<\/li>\n<li><code>Char.isLowerCase()<\/code>, <code>Char.isUpperCase()<\/code>, <code>Char.isTitleCase()<\/code> que comprueban si un caracter es may\u00fascula o min\u00fascula.<\/li>\n<li><code>Char.isDefined()<\/code> que comprueba si un caracter tiene una <a href=\"https:\/\/unicode.org\/reports\/tr44\/#General_Category_Values\" target=\"_blank\" rel=\"noopener\">categor\u00eda general Unicode<\/a> distinta de <code>Cn<\/code> (<em>undefined<\/em>).<\/li>\n<li><code>Char.isISOControl()<\/code> que comprueba si un caracter es un <a href=\"https:\/\/en.wikipedia.org\/wiki\/Control_character\" target=\"_blank\" rel=\"noopener\">caracter de control ISO<\/a>, que cuenta con un c\u00f3digo en los intervalos <code>\\u0000<\/code>..<code>\\u001F<\/code> o <code>\\u007F<\/code>..<code>\\u009F<\/code>.<\/li>\n<\/ul>\n<p>La propiedad <code>Char.category<\/code> y su clase <code>CharCategory<\/code>, que indica la categor\u00eda general de un caracter seg\u00fan Unicode, est\u00e1 ahora disponilble en proyectos multiplataforma.<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    val array = &quot;Kotlin 1.5.0-RC&quot;.toCharArray()\n    val (letterOrDigit, punctuation) = array.partition { it.isLetterOrDigit() }\n    val (upperCase, notUpperCase ) = array.partition { it.isUpperCase() }\n\n    println(&quot;$letterOrDigit, $punctuation&quot;) \/\/ [K, o, t, l, i, n, 1, 5, 0, R, C], [ , ., ., -]\n    println(&quot;$upperCase, $notUpperCase&quot;) \/\/ [K, R, C], [o, t, l, i, n, , 1, ., 5, ., 0, -]\n\n    if (array[0].isDefined()) println(array[0].category)\n\/\/sampleEnd\n}\n<\/pre>\n<h2>Versiones estrictas de String?.toBoolean()<\/h2>\n<p>La funci\u00f3n de Kotlin <code>String?.toBoolean()<\/code> se usa en gran medida para crear valores booleanos a partir de cadenas. Su funcionaomiento es muy sencillo: es <code>true<\/code> en una cadena &quot;true&quot; independientemente de si es may\u00fascula y min\u00fascula y <code>false<\/code> en todas las dem\u00e1s cadenas, incluyendo <code>null<\/code>.<\/p>\n<p>Aunque este comportamiento parece natural, puede ocultar situaciones potencialmente err\u00f3neas. Convierta lo que convierta con esta funci\u00f3n, obtendr\u00e1 una booleana incluso si la cadena tiene un valor inesperado.<\/p>\n<p>Dispone de nuevas versiones estrictas sensibles a las may\u00fasculas de <a href=\"https:\/\/kotlinlang.org\/api\/latest\/jvm\/stdlib\/kotlin.text\/to-boolean.html\" target=\"_blank\" rel=\"noopener\">String?.toBoolean()<\/a> para evitar dichos errores:<\/p>\n<ul>\n<li><code>String.toBooleanStrict()<\/code> lanza una excepci\u00f3n para todas las entradas excepto literales &#8220;true&#8221; y &#8220;false&#8221;.<\/li>\n<li><code>String.toBooleanStrictOrNull()<\/code> devuelve null para todas las entradas excepto literales &#8220;true&#8221; y &#8220;false&#8221;.<\/li>\n<\/ul>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    println(&quot;true&quot;.toBooleanStrict()) \/\/ True\n    \/\/ println(&quot;1&quot;.toBooleanStrict()) \/\/ Exception\n    println(&quot;1&quot;.toBooleanStrictOrNull()) \/\/ null\n    println(&quot;True&quot;.toBooleanStrictOrNull()) \/\/ null: the function is case-sensitive\n\/\/sampleEnd\n}\n<\/pre>\n<p><a name = \"duration-api-changes\"><\/a><\/p>\n<h2>Cambios en la API Duration<\/h2>\n<p>La <a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2019\/08\/kotlin-1-3-50-released\/#time-measurement-api\">API de medici\u00f3n de tiempo y duraci\u00f3n<\/a> experimental ha estado disponible dentro de la stdlib desde la versi\u00f3n 1.3.50. Ofrece una API para la medici\u00f3n precisa de los intervalos de tiempo.<\/p>\n<p>Una de las clases clave de esta API es <a href=\"https:\/\/kotlinlang.org\/api\/latest\/jvm\/stdlib\/kotlin.time\/-duration\/\" target=\"_blank\" rel=\"noopener\"><code>Duration<\/code><\/a>. Representa la cantidad de tiempo entre dos momentos temporales. En 1.5.0, <code>Duration<\/code> se somete a cambios significativos tanto en la API como en la representaci\u00f3n interna.<\/p>\n<p><code>Duration<\/code> ahora utiliza un valor <code>Long<\/code> para la representaci\u00f3n interna en lugar de <code>Double<\/code>. El intervalo de los valores <code>Long<\/code> permite representar m\u00e1s de cien a\u00f1os con precisi\u00f3n de nanosegundos o cien millones de a\u00f1os con precisi\u00f3n de milisegundos. No obstante, las duraciones de subnanosegundos anteriormente compatibles ya no est\u00e1n disponibles.<\/p>\n<p>Tambi\u00e9n vamos a introducir nuevas propiedades para recuperar una duraci\u00f3n como valor <code>Long<\/code>. Est\u00e1n disponibles para varias unidades de tiempo: <code>Duration.inWholeMinutes<\/code>, <code>Duration.inWholeSeconds<\/code> y otras. Estas funciones sustituir\u00e1n a las propiedades basadas en <code>Double<\/code> como <code>Duration.inMinutes<\/code>.<\/p>\n<p>Otro cambio es una serie de nuevas funciones de f\u00e1brica para crear instancias de <code>Duration<\/code> a partir de valores enteros. Se definen directamente en el tipo <code>Duration<\/code> y sustituyen a las antiguas propiedades de extensi\u00f3n de tipos num\u00e9ricos como <code>Int.seconds<\/code>.<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nimport kotlin.time.ExperimentalTime\nimport kotlin.time.Duration\n\n@ExperimentalTime\nfun main() {\n    val duration = Duration.milliseconds(120000)\n    println(&quot;There are ${duration.inWholeSeconds} seconds in ${duration.inWholeMinutes} minutes&quot;)\n}\n<\/pre>\n<p>Dados estos importantes cambios, toda la API de duraci\u00f3n y medici\u00f3n del tiempo sigue siendo experimental en 1.5.0 y requiere un opt-in con la anotaci\u00f3n <code>@ExperimentalTime<\/code>.<\/p>\n<p>Pruebe la nueva versi\u00f3n y env\u00edenos su feedback a trav\u00e9s de nuestro sistema de seguimiento de incidencias <a href=\"https:\/\/kotl.in\/issue\" target=\"_blank\" rel=\"noopener\">YouTrack<\/a>.<\/p>\n<p><a name = \"math-operations-floordiv-mod\"><\/a><\/p>\n<h2>Operaciones matem\u00e1ticas: <i>floored division<\/i> y el <i>mod operator<\/i><\/h2>\n<p>En Kotlin, el <a href=\"https:\/\/kotlinlang.org\/docs\/basic-types.html#operations\" target=\"_blank\" rel=\"noopener\">s\u00edmbolo de divisi\u00f3n (<code>\/<\/code>) en n\u00fameros enteros<\/a> representa la <em>divisi\u00f3n truncada<\/em>, que omite la parte fraccionada del resultado. En la aritm\u00e9tica modular, tambi\u00e9n existe una alternativa: <em>floored division<\/em>, que redondea el resultado (hacia el n\u00famero entero justo por debajo), lo cual da un resultado diferente en n\u00fameros negativos.<\/p>\n<p>Anteriormente, la floored division requer\u00eda una funci\u00f3n personalizada como:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun floorDivision(i: Int, j: Int): Int {\n    var result = i \/ j\n    if (i != 0 &amp;&amp; result &lt;= 0) result--\n    return result\n}\n<\/pre>\n<p>En 1.5.0-RC, representamos la funci\u00f3n <code>floorDiv()<\/code> que realiza la floored division en n\u00fameros enteros.<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    println(&quot;Truncated division -5\/3: ${-5 \/ 3}&quot;)\n    println(&quot;Floored division -5\/3: ${(-5).floorDiv(3)}&quot;)\n\/\/sampleEnd\n}\n<\/pre>\n<p>En 1.5.0, introducimos la nueva funci\u00f3n <code>mod()<\/code>. Ahora funciona exactamente como su nombre sugiere: devuelve el <em>m\u00f3dulo<\/em> recordatorio de la floored division.<\/p>\n<p>Es distinto del <code>rem()<\/code> (u operador <code>%<\/code>) de Kotlin. El m\u00f3dulo es la diferencia entre <code>a<\/code> y <code>a.floorDiv(b) * b<\/code>. Un m\u00f3dulo no cero siempre tiene el mismo s\u00edmbolo que <code>b<\/code>, mientras que <code>a % b<\/code> puede tener uno distinto. Esto puede resultar \u00fatil, por ejemplo, al implementar listas c\u00edclicas:<\/p>\n<pre class=\"kotlin-code\" data-version=\"1.5.0-RC\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nfun main() {\n\/\/sampleStart\n    fun getNextIndexCyclic(current: Int, size: Int ) = (current + 1).mod(size)\n    fun getPreviousIndexCyclic(current: Int, size: Int ) = (current - 1).mod(size)\n    \/\/ unlike %, mod() produces the expected non-negative value even if (current - 1) is less than 0\n\n    val size = 5\n    for (i in 0..(size * 2)) print(getNextIndexCyclic(i, size))\n    println()\n    for (i in 0..(size * 2)) print(getPreviousIndexCyclic(i, size))\n\/\/sampleEnd\n}\n<\/pre>\n<p><a name = \"collections-firstnotnullof\"><\/a><\/p>\n<h2>Colecciones: firstNotNullOf() y firstNotNullOfOrNull()<\/h2>\n<p>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.<\/p>\n<p>Por ejemplo, para obtener el primer resultado no null de una funci\u00f3n de selector en los elementos de la colecci\u00f3n, podr\u00eda llamar a <code>mapNotNull()<\/code> y <code>first()<\/code>. En 1.5.0, puede hacerlo con una sola llamada de una nueva funci\u00f3n <code>firstNotNullOf()<\/code>. Junto con <code>firstNotNullOf()<\/code>, a\u00f1adimos su contraparte <code>*orNull()<\/code> que produce null si no hay un valor que devolver.<\/p>\n<p>Este es un ejemplo de c\u00f3mo puede abreviar su c\u00f3digo.<\/p>\n<p>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.<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nclass Item(val name: String?)\n<\/pre>\n<p>You can implement this by iterating the collection and checking if a property is not null:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n\/\/ Option 1: manual implementation\nfor (element in collection) {\n    val itemName = element.name\n    if (itemName != null) return itemName\n}\nreturn null\n<\/pre>\n<p>Otro modo es utilizar las funciones previamente existentes <code>mapNotNull()<\/code> y <code>firstOrNull()<\/code>. Tenga en cuenta que <code>mapNotNull()<\/code> crea una colecci\u00f3n inmediata, que requiere memoria adicional, especialmente para grandes colecciones. As\u00ed pues, ah\u00ed tambi\u00e9n podr\u00eda necesitarse una transformaci\u00f3n en secuencia.<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n\/\/ Option 2: old stdlib functions\nreturn collection\n    \/\/ .asSequence() \/\/ Avoid creating intermediate list for big collections\n    .mapNotNull { it.name }\n    .firstOrNull()\n<\/pre>\n<p>Y esta es su apariencia con la nueva funci\u00f3n:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n\/\/ Option 3: new firstNotNullOfOrNull()\nreturn collection.firstNotNullOfOrNull { it.name }\n<\/pre>\n<p><a name = \"test-library-changes\"><\/a><\/p>\n<h2>Cambios en bibliotecas de pruebas<\/h2>\n<p>No hab\u00edamos realizado grandes actualizaciones en la biblioteca de pruebas de Kotlin <code>kotlin-test<\/code> en varias versiones, pero ahora vamos a incluir algunos esperados cambios. Con 1.5.0-RC, puede probar varias nuevas funcionalidades:<\/p>\n<ul>\n<li>Dependencia individual de <code>kotlin-test<\/code> en proyectos multiplataforma.<\/li>\n<li>Selecci\u00f3n autom\u00e1tica de un marco de pruebas para conjuntos de fuentes Kotlin\/JVM.<\/li>\n<li>Actualizaciones en la funci\u00f3n de aserci\u00f3n.<\/li>\n<\/ul>\n<h3>Dependencia de kotlin-test en proyectos multiplataforma<\/h3>\n<p>Vamos a continuar nuestro desarrollo del proceso de configuraci\u00f3n para proyectos multiplataforma. En 1.5.0, hemos facilitado la configuraci\u00f3n de una dependencia en <code>kotlin-test<\/code> para todos los conjuntos de fuentes.<\/p>\n<p>Ahora, la dependencia de <code>kotlin-test<\/code> en el conjunto de fuentes de prueba comunes es el \u00fanico que tiene que a\u00f1adir. El complemento Gradle inferir\u00e1 la dependencia de plataforma correspondiente para otros conjuntos de fuentes:<\/p>\n<ul>\n<li><code>kotlin-test-junit<\/code> para conjuntos de fuentes JVM. Tambi\u00e9n puede cambiar a <code>kotlin-test-junit-5<\/code> o <code>kotlin-test-testng<\/code> si las habilita expl\u00edcitamente (siga leyendo para saber c\u00f3mo).<\/li>\n<li><code>kotlin-test-js<\/code> para conjuntos de fuentes Kotlin\/JS.<\/li>\n<li><code>kotlin-test-common<\/code> y <code>kotlin-test-annotations-common<\/code> para conjuntos de fuentes comunes.<\/li>\n<li>Sin artefacto extra para conjuntos de fuentes Kotlin\/Native, porque Kotlin\/Native ofrece implementaciones integradas de la API <code>kotlin-test<\/code>.<\/li>\n<\/ul>\n<h3>Selecci\u00f3n autom\u00e1tica de un marco de pruebas para conjuntos de fuentes Kotlin\/JVM<\/h3>\n<p>Cuando especifica la dependencia <code>kotlin-test<\/code> en el conjunto de fuentes de prueba comunes tal y como se ha descrito anteriormente, los conjuntos de fuentes JVM reciben autom\u00e1ticamente la dependencia en JUnit 4. \u00a1Y ya est\u00e1! \u00a1Puede escribir y ejecutar pruebas inmediatamente!<\/p>\n<p>As\u00ed se ve en el DSL Groovy:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nkotlin {\n    sourceSets {\n        commonTest {\n            dependencies {\n                 \/\/ This brings the dependency\n                \/\/ on JUnit 4 transitively\n                implementation kotlin('test')\n            }\n        }\n    }\n}\n<\/pre>\n<\/p>\n<p>Y en el DSL de Kotlin es:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nkotlin {\n    sourceSets {\n        val commonTest by getting {\n            dependencies {\n                \/\/ This brings the dependency\n                \/\/ on JUnit 4 transitively\n                implementation(kotlin(&quot;test&quot;))\n            }\n        }\n    }\n}\n<\/pre>\n<p>Tambi\u00e9n puede cambiar a JUnit 5 o TestNG simplemente llamando a una funci\u00f3n en la tarea de prueba <a href=\"https:\/\/docs.gradle.org\/current\/javadoc\/org\/gradle\/api\/tasks\/testing\/Test.html#useJUnitPlatform--\" target=\"_blank\" rel=\"noopener\"><code>useJUnitPlatform()<\/code><\/a> o <a href=\"https:\/\/docs.gradle.org\/current\/javadoc\/org\/gradle\/api\/tasks\/testing\/Test.html#useTestNG--\" target=\"_blank\" rel=\"noopener\"><code>useTestNG()<\/code><\/a>.<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\nkotlin {\n    jvm {\n        testRuns[&quot;test&quot;].executionTask.configure {\n            \/\/ enable TestNG support\n            useTestNG()\n            \/\/ or\n            \/\/ enable JUnit Platform (a.k.a. JUnit 5) support\n            useJUnitPlatform()\n        }\n    }\n}\n<\/pre>\n<p>Lo mismo sucede en proyectos solo JVM cuando a\u00f1ade la dependencia <code>kotlin-test<\/code>.<\/p>\n<h3>Actualizaciones en las funciones de aserci\u00f3n<\/h3>\n<p>Para 1.5.0, hemos preparado varias nuevas funciones de aserci\u00f3n, junto con mejoras en las ya existentes.<\/p>\n<p>En primer lugar, echemos un vistazo r\u00e1pido a las nuevas funciones:<\/p>\n<ul>\n<li><code>assertIs&lt;T&gt;()<\/code> y <code>assertIsNot&lt;T&gt;()<\/code> comprueban el tipo de valor.<\/li>\n<li><code>assertContentEquals()<\/code> compara el contenido del contenedor en cuanto a vectores, secuencias y cualquier <code>Iterable<\/code>. M\u00e1s espec\u00edficamente, comprueba si <code>expected<\/code> y <code>actual<\/code> contienen los mismos elementos en el mismo orden.<\/li>\n<li><code>assertEquals()<\/code> y <code>assertNotEquals()<\/code> para <code>Double<\/code> y <code>Float<\/code> cuentan con nuevas sobrecargas con un tercer par\u00e1metro: precisi\u00f3n.<\/li>\n<li><code>assertContains()<\/code> comprueba la presencia de un elemento en cualquier objeto con el operador <code>contains()<\/code> definido: vector, lista, intervalo, etc.<\/li>\n<\/ul>\n<p>Este es un breve ejemplo que muestra el uso de estas funciones:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\">\n@Test\nfun test() {\n    val expectedArray = arrayOf(1, 2, 3)\n    val actualArray = Array(3) { it + 1 }\n\n    val first: Any = actualArray[0]\n    assertIs&lt;Int&gt;(first)\n    \/\/ first is smart-cast to Int now\n    println(&quot;${first + 1}&quot;)\n\n    assertContentEquals(expectedArray, actualArray)\n    assertContains(expectedArray, 2)\n\n    val x = sin(PI)\n\n    \/\/ precision parameter\n    val tolerance = 0.000001\n\n    assertEquals(0.0, x, tolerance)\n}\n<\/pre>\n<p>Con respecto a las funciones de aserci\u00f3n existentes: ahora se puede llamar a <a href=\"https:\/\/kotlinlang.org\/docs\/composing-suspending-functions.html\" target=\"_blank\" rel=\"noopener\">funciones de suspensi\u00f3n<\/a> dentro de lambda pasadas a <code>assertTrue()<\/code>, <code>assertFalse()<\/code> y <code>expect()<\/code> porque estas funciones est\u00e1n ahora <a href=\"https:\/\/kotlinlang.org\/docs\/inline-functions.html\" target=\"_blank\" rel=\"noopener\">alineadas<\/a>.<\/p>\n<h2>Pruebe todas las funcionalidades de Kotlin 1.5.0<\/h2>\n<p>\u00a1Use estas modernas API de Kotlin en sus proyectos reales con 1.5.0-RC!<\/p>\n<p>En IntelliJ IDEA o Android Studio, instale el complemento Kotlin 1.5.0-RC. Descubra <a href=\"https:\/\/kotlinlang.org\/docs\/install-eap-plugin.html\" target=\"_blank\" rel=\"noopener\">c\u00f3mo obtener las versiones anticipadas de los complementos<\/a>.<\/p>\n<p>Cree sus proyectos existentes con 1.5.0-RC para comprobar c\u00f3mo funcionar\u00e1n con 1.5.0. Con la <a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2021\/03\/kotlin-1-5-0-m2-released\/\">nueva configuraci\u00f3n simplificada para lanzamientos en vista previa<\/a>, solo tiene que pasarse a la versi\u00f3n de Kotlin <code>1.5.0-RC<\/code> y <a href=\"https:\/\/kotlinlang.org\/docs\/eap.html#build-details\" target=\"_blank\" rel=\"noopener\">ajustar las versiones de dependencia<\/a> si fuese necesario.<\/p>\n<p align=\"center\"><a class=\"jb-download-button\" title=\"Instalar\" href=\"https:\/\/kotlinlang.org\/docs\/install-eap-plugin.html\" target=\"_blank\" rel=\"noopener\">Instale 1.5.0-RC<\/a><\/p>\n<p>Como siempre, puede probar la \u00faltima versi\u00f3n online en el <a href=\"https:\/\/play.kotlinlang.org\" target=\"_blank\" rel=\"noopener\">Kotlin Playground<\/a>.<\/p>\n<h2>Compatibilidad<\/h2>\n<p>Como en todas las versiones, algunos ciclos de entrada en desuso de cambios anunciados previamente llegar\u00e1n a su fin con Kotlin 1.5.0. El comit\u00e9 del lenguaje ha revisado detenidamente todos estos casos y los ha incluido en la <a href=\"https:\/\/kotlinlang.org\/docs\/compatibility-guide-15.html\" target=\"_blank\" rel=\"noopener\">Gu\u00eda de compatibilidad de Kotlin 1.5<\/a>. Tambi\u00e9n puede consultar dichos cambios en <a href=\"https:\/\/youtrack.jetbrains.com\/issues\/KT?q=Tag:%20language-committee-approved%20Target%20versions:%201.5.0-RC,%201.5.0-M2,%201.5.0-M1,%201.5.0\" target=\"_blank\" rel=\"noopener\">YouTrack<\/a>.<\/p>\n<h3>Notas sobre el lanzamiento<\/h3>\n<p>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\u00e1 garantizado que los binarios creados con Kotlin 1.5-RC sean compatibles con Kotlin 1.5.0-RC.<\/p>\n<h2>Env\u00edenos sus comentarios<\/h2>\n<p>\u00a1Esta es su \u00faltima oportunidad de participar en el siguiente lanzamiento de funcionalidades! Comparta con nosotros cualquier incidencia que encuentre en el <a href=\"https:\/\/kotl.in\/issue\" target=\"_blank\" rel=\"noopener\">sistema de seguimiento de incidencias<\/a>. \u00a1Mejore Kotlin 1.5.0 para usted y para la comunidad!<\/p>\n<p align=\"center\"><a class=\"jb-download-button\" title=\"Instalar\" href=\"https:\/\/kotlinlang.org\/docs\/install-eap-plugin.html\" target=\"_blank\" rel=\"noopener\">Instale 1.5.0-RC<\/a><\/p>\n","protected":false},"author":1086,"featured_media":136578,"comment_status":"closed","ping_status":"closed","template":"","categories":[4113,907],"tags":[21,6408,477],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/kotlin\/138784"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/kotlin"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/types\/kotlin"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/comments?post=138784"}],"version-history":[{"count":1,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/kotlin\/138784\/revisions"}],"predecessor-version":[{"id":138785,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/kotlin\/138784\/revisions\/138785"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media\/136578"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media?parent=138784"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/categories?post=138784"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/tags?post=138784"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/cross-post-tag?post=138784"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}