{"id":99828,"date":"2020-12-02T14:32:29","date_gmt":"2020-12-02T13:32:29","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=kotlin&#038;p=99828"},"modified":"2020-12-02T14:32:29","modified_gmt":"2020-12-02T13:32:29","slug":"lanzamiento-de-kotlin-1-4-20","status":"publish","type":"kotlin","link":"https:\/\/blog.jetbrains.com\/es\/kotlin\/2020\/12\/lanzamiento-de-kotlin-1-4-20\/","title":{"rendered":"Lanzamiento de Kotlin 1.4.20"},"content":{"rendered":"<p>Kotlin 1.4.20 ha llegado con nuevas funcionalidades experimentales que ya puede probar. Uno de los principios b\u00e1sicos del equipo de Kotlin es estar abiertos a los comentarios de la comunidad, y nos gusta contar con su opini\u00f3n sobre los prototipos de las nuevas funcionalidades. <a href=\"#how-to-update\">Pru\u00e9belas<\/a> y env\u00edenos sus comentarios a <a href=\"http:\/\/kotlinlang.slack.com\/\" target=\"_blank\" rel=\"noopener\">Slack<\/a> (obtenga una invitaci\u00f3n <a href=\"https:\/\/surveys.jetbrains.com\/s3\/kotlin-slack-sign-up?_ga=2.134077326.1218289669.1605167163-154294388.1603171954\" target=\"_blank\" rel=\"noopener\">aqu\u00ed<\/a> o en <a href=\"https:\/\/youtrack.jetbrains.com\/issues\/KT\" target=\"_blank\" rel=\"noopener\">YouTrack<\/a>).<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2020\/11\/banners_twitter.png\" alt=\"Kotlin 1.4.20\" \/><\/p>\n<p>Estos son algunos de los puntos m\u00e1s destacados:<\/p>\n<ul>\n<li>Compatibilidad con nuevas funcionalidades de JVM, como concatenaci\u00f3n de cadenas mediante invokedynamic.<\/li>\n<li>Rendimiento mejorado y gesti\u00f3n de excepciones para proyectos KMM.<\/li>\n<li>Extensiones para la ruta JDK: <code>Path(\u201cdir\u201d) \/ \u201cfile.txt\u201d<\/code>.<\/li>\n<\/ul>\n<p>Tambi\u00e9n estamos incluyendo numerosas soluciones y mejoras para funcionalidades existentes, incluidas las a\u00f1adidas en 1.4.0. As\u00ed que, si tuvo alg\u00fan problema con alguna de esas funcionalidades, ahora es un buen momento para darles otra oportunidad.<\/p>\n<p>Contin\u00fae leyendo para obtener m\u00e1s informaci\u00f3n acerca de las funcionalidades de Kotlin 1.4.20. Tambi\u00e9n encontrar\u00e1 un breve resumen sobre esta versi\u00f3n en la p\u00e1gina <a href=\"https:\/\/kotlinlang.org\/docs\/reference\/whatsnew1420.html\" target=\"_blank\" rel=\"noopener\"> Novedades de Kotlin 1.4.20<\/a> en Kotlin docs. Puede encontrar la lista completa de cambios en el <a href=\"https:\/\/github.com\/JetBrains\/kotlin\/blob\/1.4.20\/ChangeLog.md\" target=\"_blank\" rel=\"noopener\">registro de cambios<\/a>.<\/p>\n<p>Como siempre, nos gustar\u00eda agradecer a nuestros <a href=\"#external-contributors\">colaboradores externos<\/a> que nos han ayudado con este lanzamiento.<\/p>\n<p>Ahora \u00a1entremos en materia!<\/p>\n<h2>Kotlin\/JVM<\/h2>\n<p><a name=\"kotlin-jvm\"><\/a><\/p>\n<p>En la JVM hemos a\u00f1adido el nuevo destino JVM 15, y nos hemos centrado principalmente en mejorar la funcionalidad y el rendimiento existentes, as\u00ed como en solucionar errores.<\/p>\n<h3>Concatenaci\u00f3n de cadenas invokedynamic<\/h3>\n<p>Desde Java 9, la concatenaci\u00f3n de cadenas en JVM se hab\u00eda realizado mediante la <a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/technotes\/guides\/vm\/multiple-language-support.html#invokedynamic\" target=\"_blank\" rel=\"noopener\">invocaci\u00f3n de m\u00e9todos din\u00e1micos<\/a> (la instrucci\u00f3n <code>invokedynamic<\/code> en el bytecode). Esto funciona m\u00e1s r\u00e1pido y consume menos memoria que la implementaci\u00f3n anterior, y deja espacio a futuras optimizaciones sin necesitar cambios en el bytecode.<\/p>\n<p>Hemos comenzado a implementar este mecanismo en Kotlin para un mejor rendimiento, y ahora puede copilar concatenaciones de cadenas en invocaciones din\u00e1micas en destinos JVM 9+.<\/p>\n<p>Actualmente, esta funcionalidad es experimental, y cubre los casos siguientes:<\/p>\n<ul>\n<li><code>String.plus<\/code> en el operador (<code>a + b<\/code>), (<code>a.plus(b)<\/code>) expl\u00edcito y referencias (<code>(a::plus)(b)<\/code>).<\/li>\n<li><code>toString<\/code> en clases de datos inline.<\/li>\n<li>Plantillas de cadenas, excepto para aquellas con un argumento individual no constante (v\u00e9ase <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KT-42457\" target=\"_blank\" rel=\"noopener\">KT-42457<\/a>).<\/li>\n<\/ul>\n<p>Para permitir la concatenaci\u00f3n de cadenas <code>invokedynamic<\/code>, a\u00f1ada la opci\u00f3n del compilador <code>-Xstring-concat<\/code> con uno de los valores siguientes:<\/p>\n<ul>\n<li><code>indy-with-constants<\/code> para realizar concatenaciones <code>invokedynamic<\/code> en cadenas con <a href=\"https:\/\/docs.oracle.com\/javase\/9\/docs\/api\/java\/lang\/invoke\/StringConcatFactory.html#makeConcatWithConstants-java.lang.invoke.MethodHandles.Lookup-java.lang.String-java.lang.invoke.MethodType-java.lang.String-java.lang.Object...-\" target=\"_blank\" rel=\"noopener\">StringConcatFactory.makeConcatWithConstants()<\/a> (se planea que esta funci\u00f3n pase a ser predeterminada para destinos JVM 9 y posteriores a partir de 1.5).<\/li>\n<li><code>indy<\/code> para realizar concatenaciones <code>invokedynamic<\/code> en cadenas con <a href=\"https:\/\/docs.oracle.com\/javase\/9\/docs\/api\/java\/lang\/invoke\/StringConcatFactory.html#makeConcat-java.lang.invoke.MethodHandles.Lookup-java.lang.String-java.lang.invoke.MethodType-\" target=\"_blank\" rel=\"noopener\">StringConcatFactory.makeConcat()<\/a>.<\/li>\n<li><code>inline<\/code> para volver a la concatenaci\u00f3n cl\u00e1sica v\u00eda <code>StringBuilder.append()<\/code>.<\/li>\n<\/ul>\n<h2>Kotlin\/JS<\/h2>\n<p><a name=\"kotlin-js\"><\/a><\/p>\n<p>Kotlin\/JS contin\u00faa evolucionando r\u00e1pidamente, y esta versi\u00f3n incorpora diversas mejoras, incluyendo nuevas plantillas para su asistente de proyectos, DSL mejorado para un mejor control de la configuraci\u00f3n del proyecto, y muchas m\u00e1s. El nuevo compilador de IR tambi\u00e9n cuenta ahora con un modo totalmente nuevo de compilar proyectos con errores.<\/p>\n<h3>Cambios en el DSL de Gradle<\/h3>\n<p>El Gradle DSL de Kotlin\/JS ha experimentado numerosas actualizaciones que simplifican la configuraci\u00f3n y personalizaci\u00f3n de los proyectos, entre las que se incluyen ajustes de configuraci\u00f3n de webpack, modificaciones en el archivo autogenerado package.json, y un control mejorado de las dependencias transitivas.<\/p>\n<h4>Un punto \u00fanico para la configuraci\u00f3n de webpack<\/h4>\n<p>Kotlin 1.4.20 incorpora un nuevo bloque de configuraci\u00f3n para el destino <code>browser<\/code> denominado <code>commonWebpackConfig<\/code>. Desde \u00e9l puede ajustar configuraciones habituales desde un \u00fanico punto, en lugar de duplicar configuraciones para <code>webpackTask<\/code>, <code>runTask<\/code> y <code>testTask<\/code>.<\/p>\n<p>Para permitir la compatibilidad con CSS de forma predeterminada para las tres tareas, tiene que incluir el fragmento siguiente en el <code>build.gradle(.kts)<\/code> de su proyecto:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\"> kotlin { browser { commonWebpackConfig { cssSupport.enabled = true } binaries.executable() } } <\/pre>\n<h4>Personalizaci\u00f3n de package.json desde Gradle<\/h4>\n<p>El archivo <code>package.json<\/code> suele definir c\u00f3mo deber\u00eda comportarse un proyecto JavaScript, identificando scripts disponibles para su ejecuci\u00f3n, dependencias, etc. Para los proyectos Kotlin\/JS se genera autom\u00e1ticamente en el momento de su creaci\u00f3n. Como el contenido de <code>package.json<\/code> var\u00eda de un caso a otro, nos han pedido mucho un modo f\u00e1cil de personalizar este archivo.<\/p>\n<p>A partir de Kotlin 1.4.20, puede a\u00f1adir entradas al archivo de proyecto <code>package.json<\/code> a partir del script de creaci\u00f3n de Gradle. Para a\u00f1adir campos personalizados a su <code>package.json<\/code>, utilice la funci\u00f3n <code>customField<\/code> en el bloque de compilaciones <code>packageJson<\/code>:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\"> kotlin { js(BOTH) { compilations[&quot;main&quot;].packageJson { customField(&quot;hello&quot;, mapOf(&quot;one&quot; to 1, &quot;two&quot; to 2)) } } } <\/pre>\n<p>Cuando cree el proyecto, esto a\u00f1adir\u00e1 el siguiente bloque al archivo de configuraci\u00f3n <code>build\/js\/packages\/projectName\/package.json<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">&quot;hello&quot;: {\n  &quot;one&quot;: 1,\n  &quot;two&quot;: 2\n}<\/pre>\n<p>Tanto si desea a\u00f1adir un campo de scripts a la configuraci\u00f3n para facilitar la ejecuci\u00f3n de su proyecto desde la l\u00ednea de comandos, como si quiere incluir informaci\u00f3n para otras herramientas de posprocesamiento, esperamos que este nuevo modo de especificar campos personalizados le resulte \u00fatil.<\/p>\n<h4>Resoluciones de dependencias de Yarn selectivas (experimental)<\/h4>\n<p>Al incluir dependencias desde npm, en ocasiones desea tener un control m\u00e1s preciso de sus dependencias (<em>dependencias transitivas<\/em>). Existen numerosos motivos por los que podr\u00eda darse este caso. Quiz\u00e1 desee aplicar un mejora importante a una de las dependencias de una biblioteca que est\u00e1 utilizando. O puede que quiera retirar una actualizaci\u00f3n de una dependencia transitiva que actualmente estropea su aplicaci\u00f3n. Las <a href=\"https:\/\/classic.yarnpkg.com\/en\/docs\/selective-version-resolutions\/\" target=\"_blank\" rel=\"noopener\">resoluciones de dependencias selectivas<\/a> de Yarn le permiten saltarse las dependencias especificadas por el autor original, para que pueda continuar desarrollando.<\/p>\n<p>Con Kotlin 1.4.20, ofrecemos un modo preliminar (experimental) de configurar esta funcionalidad a partir de un script de compilaci\u00f3n de un proyecto de Gradle. Mientras seguimos trabajando en una perfecta integraci\u00f3n API con el resto de las opciones de Kotlin\/JS, ya puede utilizar la funcionalidad a trav\u00e9s de la <code>YarnRootExtension<\/code> que encontrar\u00e1 en el <code>YarnPlugin<\/code>. Para incidir en la versi\u00f3n resuelta de un paquete para su proyecto, utilice la funci\u00f3n <code>resolution<\/code>. En sus argumentos, especifique el selector de nombre de paquete (como indica <a href=\"https:\/\/classic.yarnpkg.com\/en\/docs\/selective-version-resolutions\/\" target=\"_blank\" rel=\"noopener\">Yarn<\/a>) y la versi\u00f3n deseada.<\/p>\n<p>Una configuraci\u00f3n de ejemplo para la resoluci\u00f3n de dependencias selectiva en su archivo <code>build.gradle.kts<\/code> ser\u00eda as\u00ed:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\"> rootProject.plugins.withType(YarnPlugin::class.java) { rootProject.the&lt;YarnRootExtension&gt;().apply { resolution(&quot;react&quot;, &quot;16.0.0&quot;) resolution(&quot;processor\/decamelize&quot;, &quot;3.0.0&quot;) } } <\/pre>\n<p>Aqu\u00ed, <em>todas<\/em> sus dependencias de npm que requieren <code>react<\/code> recibir\u00e1n la versi\u00f3n <code>16.0.0<\/code>, y <code>processor<\/code> recibir\u00e1 su dependencia <code>decamelize<\/code> como versi\u00f3n <code>3.0.0<\/code>. Adem\u00e1s, tambi\u00e9n puede pasar las invocaciones <code>include<\/code> y <code>exclude<\/code> al bloque <code>resolution<\/code>, lo que le permitir\u00e1 especificar restricciones acerca de versiones aceptables.<\/p>\n<h4>Deshabilitar espacios de trabajo dispersos (experimental)<\/h4>\n<p>Para abreviar los tiempos de creaci\u00f3n, el complemento de Gradle para Kotlin\/JS solo instala dependencias necesarias para una tarea en particular de Gradle. Por ejemplo, el paquete <code>webpack-dev-server<\/code> solo se instala cuando ejecuta una de las tareas <code>*Run<\/code>, y no cuando ejecuta la tarea <code>assemble<\/code>. Aunque esto significa que se evitan descargas innecesarias, puede crear problemas al ejecutar varios procesos de Gradle en paralelo. Cuando los requisitos de dependencias chocan, las dos instalaciones de paquetes npm pueden causar errores.<\/p>\n<p>Para resolver este problema, Kotlin 1.4.20 incluye una nueva opci\u00f3n (experimental) para deshabilitar los denominados <em>espacios de trabajo dispersos<\/em>. Como la compatibilidad experimental con resoluciones de dependencias selectivas, esta funcionalidad tambi\u00e9n est\u00e1 accesible actualmente a trav\u00e9s de <code>YarnRootExtension<\/code>, pero probablemente se integrar\u00e1 mejor con el resto de DSL de Gradle para Kotlin\/JS. Para utilizarla, a\u00f1ada el fragmento siguiente a su archivo <code>build.gradle.kts<\/code>:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\"> rootProject.plugins.withType(YarnPlugin::class.java) { rootProject.the&lt;YarnRootExtension&gt;().disableGranularWorkspaces() } <\/pre>\n<p>Con esta configuraci\u00f3n, el complemento de Gradle para Kotlin\/JS instalar\u00e1 todas las dependencias de npm que podr\u00eda utilizar su proyecto, incluyendo las utilizadas por tareas que no se est\u00e9n ejecutando actualmente. Esto significa que el primer build de Gradle podr\u00eda tardar un poco m\u00e1s, pero las dependencias descargadas estar\u00edan actualizadas para todas las tareas que ejecute. De este modo, puede evitar conflictos al ejecutar varios procesos de Gradle en paralelo.<\/p>\n<h3>Nuevas plantillas del asistente<\/h3>\n<p>Para que disfrute de modos m\u00e1s pr\u00e1cticos de personalizar su proyecto durante la creaci\u00f3n, el asistente de proyectos de Kotlin incluye nuevas plantillas adaptables para aplicaciones Kotlin\/JS. Cuenta con plantillas tanto para el navegador como para entornos de ejecuci\u00f3n Node.js. Son un buen punto de partida para su proyecto, y permiten ajustar con precisi\u00f3n la configuraci\u00f3n inicial. Esto incluye ajustes como habilitar el nuevo compilador de IR o configurar compatibilidad con bibliotecas adicionales.<\/p>\n<p>Con Kotlin 1.4.20 dispone de tres plantillas:<\/p>\n<ul>\n<li><strong>Browser Application<\/strong> le permite configurar un proyecto b\u00e1sico de Gradle para Kotlin\/JS que se ejecuta en el navegador.<\/li>\n<li><strong>React Application<\/strong> contiene todo lo que necesita para comenzar a crear una aplicaci\u00f3n de React utilizando los <a href=\"https:\/\/github.com\/JetBrains\/kotlin-wrappers\" target=\"_blank\" rel=\"noopener\">kotlin-wrappers<\/a> adecuados. Le ofrece opciones para permitir integraciones para hojas de estilo, componentes de navegaci\u00f3n y contenedores de estados.<\/li>\n<li><strong>Node.js Application<\/strong> preconfigura su proyecto para ejecutarlo en una ejecuci\u00f3n Node.js. Incorpora la opci\u00f3n de incluir directamente el paquete experimental <a href=\"https:\/\/github.com\/Kotlin\/kotlinx-nodejs\" target=\"_blank\" rel=\"noopener\">kotlinx-nodejs<\/a>, del que ya hablamos en un <a href=\"https:\/\/blog.jetbrains.com\/kotlin\/2020\/07\/kotlin-1-4-rc-released\/#kotlin-js-node\">art\u00edculo anterior<\/a>.<\/li>\n<\/ul>\n<h3>Ignorar errores de compilaci\u00f3n (experimental)<\/h3>\n<p>Con Kotlin 1.4.20 tambi\u00e9n estamos encantados de presentar una funcionalidad totalmente nueva disponible en el <a href=\"https:\/\/kotlinlang.org\/docs\/reference\/js-ir-compiler.html\" target=\"_blank\" rel=\"noopener\">compilador IR de Kotlin\/JS<\/a> \u2013 <em>ignorar errores de compilaci\u00f3n<\/em>. Esta funcionalidad le permite probar su aplicaci\u00f3n incluso cuando se encuentra en un estado en el que normalmente no se compilar\u00eda. Por ejemplo, cuando est\u00e1 realizando una refactorizaci\u00f3n compleja o cuando trabaja en una parte del sistema que no tiene nada que ver con un error de compilaci\u00f3n. Con este nuevo modo, el compilador hace caso omiso de cualquier c\u00f3digo err\u00f3neo y lo sustituye con excepciones de ejecuci\u00f3n en lugar de impedir la compilaci\u00f3n.<\/p>\n<p>Kotlin 1.4.20 cuenta con dos pol\u00edticas de tolerancia para ignorar los errores de compilaci\u00f3n en su c\u00f3digo:<\/p>\n<ul>\n<li>En modo <code>SEMANTIC<\/code>, el compilador aceptar\u00e1 c\u00f3digo sint\u00e1cticamente correcto que no tenga sentido sem\u00e1nticamente. Un ejemplo de esto ser\u00eda una instrucci\u00f3n que contuviese un desajuste de tipo (como <code>val x: String = 3<\/code>).<\/li>\n<li>En modo <code>SYNTAX<\/code>, el compilador aceptar\u00e1 cualquier c\u00f3digo, incluso aunque contenga errores de sintaxis. Independientemente de lo que escriba, el compilador tratar\u00e1 de generar un ejecutable que funcione.<\/li>\n<\/ul>\n<p>Como funcionalidad experimental, ignorar errores de compilaci\u00f3n requiere una elecci\u00f3n a trav\u00e9s de una opci\u00f3n del compilador. Solo est\u00e1 disponible en compilador de IR Kotlin\/JS. Para habilitarla, a\u00f1ada el fragmento siguiente a su archivo <code>build.gradle.kts<\/code>:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\"> kotlin { js(IR) { compilations.all { compileKotlinTask.kotlinOptions.freeCompilerArgs += listOf(&quot;-Xerror-tolerance-policy=SYNTAX&quot;) } } } <\/pre>\n<p>Esperamos que la compilaci\u00f3n con errores le ayude a reforzar bucles de feedback y aumente su velocidad de iteraci\u00f3n al trabajar en proyectos Kotlin\/JS. Estamos deseando recibir sus comentarios, as\u00ed como cualquier incidencia que encuentre mientras prueba esta funcionalidad, en nuestro <a href=\"http:\/\/kotl.in\/issue\" target=\"_blank\" rel=\"noopener\">YouTrack<\/a>.<\/p>\n<p>Mientras continuamos refinando la implementaci\u00f3n de esta funcionalidad, tambi\u00e9n ofrecemos una integraci\u00f3n m\u00e1s profunda de ella con del DSL de Gradle para Kotlin\/JS y sus tareas m\u00e1s adelante.<\/p>\n<h2>Kotlin\/Native<\/h2>\n<p><a name=\"kotlin-native\"><\/a><\/p>\n<p>El rendimiento contin\u00faa siendo una de las principales prioridades de Kotlin\/Native en 1.4.20. Una funcionalidad clave en esta \u00e1rea es un prototipo del nuevo mecanismo de an\u00e1lisis de escape que planeamos pulir y mejorar en futuros lanzamientos. Y, por supuesto, tambi\u00e9n hay mejoras de rendimiento menores, como comprobaciones de rango m\u00e1s r\u00e1pidas (<code>in<\/code>).<\/p>\n<p>Otro aspecto de las mejoras en el desarrollo en Kotlin\/Native en 1.4.20 es el perfeccionamiento y la reparaci\u00f3n de errores. Hemos abordado una gran cantidad de antiguas incidencias, as\u00ed como las encontradas en las funcionalidades del nuevo 1.4, por ejemplo el <a href=\"https:\/\/kotlinlang.org\/docs\/reference\/mpp-share-on-platforms.html#share-code-on-similar-platforms\" target=\"_blank\" rel=\"noopener\">mecanismo para compartir c\u00f3digo<\/a>. Un conjunto de mejoras soluciona las incoherencias de comportamiento entre Kotlin\/Native y Kotlin\/JVM en casos especiales, como la inicializaci\u00f3n de propiedades o el modo en que funcionan <code>equals<\/code> y <code>hashCode<\/code> en las referencias funcionales.<\/p>\n<p>Por \u00faltimo, hemos ampliado las capacidades de interoperabilidad de Objective-C con <a href=\"#handling-objective-c-exceptions\">una opci\u00f3n de empaquetar excepciones de Objective-C en excepciones de Kotlin<\/a>, permitiendo gestionarlas en el c\u00f3digo Kotlin.<\/p>\n<h3>An\u00e1lisis de escape<\/h3>\n<p><em>Escape analysis<\/em> o an\u00e1lisis de escape es una t\u00e9cnica que utiliza el compilador para decidir si un objeto puede asignarse a la pila o deber\u00eda &quot;escapar&quot; al mont\u00f3n. La asignaci\u00f3n en las pilas es mucho m\u00e1s r\u00e1pida y no requiere recogida de basura en el futuro.<\/p>\n<p>Aunque Kotlin\/Native ya contaba con an\u00e1lisis de escape, ahora estamos introduciendo una implementaci\u00f3n de prototipos de un nuevo an\u00e1lisis de escape global m\u00e1s eficiente. Se efect\u00faa en una fase de compilaci\u00f3n por separado para los builds de lanzamiento (con la opci\u00f3n de compilador <code>-opt<\/code>).<\/p>\n<p>Este prototipo ya ha logrado algunos resultados prometedores, como un 10 % de aumento medio del rendimiento con respecto a nuestros puntos de referencia. Estamos buscando modos de optimizar el algoritmo de modo que encuentre m\u00e1s objetos para la asignaci\u00f3n de pilas y acelere el programa todav\u00eda m\u00e1s.<\/p>\n<p>Mientras seguimos trabajando en el prototipo, puede ayudarnos en gran medida prob\u00e1ndolo y compartiendo los resultados que obtiene en sus proyectos.<\/p>\n<p>Si desea deshabilitar la fase de an\u00e1lisis de escape, utilice la opci\u00f3n del compilador <code>-Xdisable-phases=EscapeAnalysis<\/code>.<\/p>\n<h3>Elecci\u00f3n de empaquetar las excepciones de Objective-C<\/h3>\n<p>El objetivo de las excepciones en Objective-C es muy distinto del de las de Kotlin. Su uso normalmente se limita a buscar errores durante el desarrollo. Pero t\u00e9cnicamente, las bibliotecas de Objective-C pueden lanzar excepciones en ejecuci\u00f3n. Anteriormente no exist\u00eda la opci\u00f3n de gestionar esas excepciones en Kotlin\/Native, y encontrarse con una <code>NSException<\/code> lanzada desde una biblioteca daba lugar a la finalizaci\u00f3n del programa de Kotlin\/Native al completo.<\/p>\n<p>En 1.4.20, hemos a\u00f1adido una opci\u00f3n para gestionar esas excepciones en ejecuci\u00f3n para evitar ca\u00eddas del programa. Puede elegir empaquetar excepciones <code>NSException<\/code> en excepciones <code>ForeignException<\/code> de Kotlin para continuar gestion\u00e1ndolas en el c\u00f3digo Kotlin. Una <code>ForeignException<\/code> as\u00ed mantiene la referencia a la <code>NSException<\/code> original, lo que le permite obtener informaci\u00f3n acerca de la causa ra\u00edz.<\/p>\n<p>Para habilitar el empaquetado de excepciones de Objective-C, especifique la opci\u00f3n <code>-Xforeign-exception-mode objc-wrap<\/code> en la llamada a <code>cinterop<\/code> o a\u00f1ada la propiedad <code>foreignExceptionMode = objc-wrap<\/code> al archivo <code>.def<\/code>. Si utiliza la <a href=\"https:\/\/kotlinlang.org\/docs\/reference\/native\/cocoapods.html\" target=\"_blank\" rel=\"noopener\">integraci\u00f3n de CocoaPods<\/a>, especifique la opci\u00f3n en el bloque de script de compilaci\u00f3n <code>pod {}<\/code> de una dependencia del modo siguiente:<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\"> pod(&quot;foo&quot;) { extraOpts = listOf(&quot;-Xforeign-exception-mode\u201d, \u201cobjc-wrap&quot;) } <\/pre>\n<p>El comportamiento predeterminado no var\u00eda: el programa finaliza cuando se lanza una excepci\u00f3n desde el c\u00f3digo de Objetive-C.<\/p>\n<h3>Mejoras en el complemento CocoaPods<\/h3>\n<h4>Ejecuci\u00f3n de tareas mejorada<\/h4>\n<p>En esta versi\u00f3n, hemos mejorado significativamente el flujo de ejecuci\u00f3n de tareas. Por ejemplo, si a\u00f1ade una nueva dependencia de CocoaPods, las dependencias existentes no vuelven a crearse. A\u00f1adir un destino extra tampoco afecta a la nueva creaci\u00f3n de dependencias para destinos existentes.<\/p>\n<h4>DSL ampliado<\/h4>\n<p>En 1.4.20 hemos ampliado el DSL para a\u00f1adir dependencias de <a href=\"https:\/\/kotlinlang.org\/docs\/reference\/native\/cocoapods.html\" target=\"_blank\" rel=\"noopener\">CocoaPods<\/a> a su proyecto de Kotlin.<\/p>\n<p>Adem\u00e1s de los Pods locales y los Pods del repositorio de Cocoa Pods, puede a\u00f1adir dependencias en los siguientes tipos de bibliotecas:<\/p>\n<ul>\n<li>Una biblioteca desde un repositorio de especificaciones personalizado.<\/li>\n<li>Una biblioteca remota desde un repositorio de Git.<\/li>\n<li>Una biblioteca desde un archivo (tambi\u00e9n disponible mediante direcci\u00f3n HTTP arbitraria).<\/li>\n<li>Una biblioteca est\u00e1tica.<\/li>\n<li>Una biblioteca con opciones cinterop personalizadas.<\/li>\n<\/ul>\n<p>Todav\u00eda se admite la sintaxis del DSL anterior.<\/p>\n<p>Echemos un vistazo a un par de cambios en el DSL en los ejemplos siguientes:<\/p>\n<ul>\n<li>\n<p><strong>Una dependencia en una biblioteca remota desde un repositorio de Git<\/strong>. Puede especificar una etiqueta, confirmaci\u00f3n o rama utilizando las palabras clave correspondientes, por ejemplo: <\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\"> pod(&quot;JSONModel&quot;) { source = git(&quot;https:\/\/github.com\/jsonmodel\/jsonmodel.git&quot;) { branch = &quot;key-mapper-class&quot; } } <\/pre>\n<\/p>\n<p>Tambi\u00e9n puede combinar estas palabras clave para obtener la versi\u00f3n necesaria de un Pod.<\/p>\n<\/li>\n<li>\n<p><strong>Una dependencia en una biblioteca desde un repositorio de especificaciones personalizado<\/strong>. Utilice para ello el par\u00e1metro especial <code>specRepos<\/code>: <\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\"> specRepos { url(&quot;https:\/\/github.com\/Kotlin\/kotlin-cocoapods-spec.git&quot;) } pod(&quot;example&quot;) <\/pre>\n<\/p>\n<\/li>\n<\/ul>\n<p>Encontrar\u00e1 m\u00e1s ejemplos en la <a href=\"https:\/\/github.com\/Kotlin\/kotlin-with-cocoapods-sample\" target=\"_blank\" rel=\"noopener\">demostraci\u00f3n de Kotlin con CocoaPods<\/a>.<\/p>\n<h4>Integraci\u00f3n con Xcode actualizada<\/h4>\n<p>Para trabajar correctamente con Xcode, Kotlin requiere algunos cambios en Podfile:<\/p>\n<ul>\n<li>\n<p>Si su Kotlin Pod tiene alguna dependencia de Git, HTTP o specRepo, deber\u00eda especificarla en el Podfile. Por ejemplo, si a\u00f1ade una dependencia en <code>AFNetworking<\/code> desde el repositorio de CocoaPods, decl\u00e1rela tambi\u00e9n en el Podfile:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">pod &#039;AFNetworking&#039;<\/pre>\n<\/li>\n<li>\n<p>Cuando a\u00f1ada una biblioteca desde la especificaci\u00f3n personalizada, tambi\u00e9n deber\u00eda indicar la <a href=\"https:\/\/guides.cocoapods.org\/syntax\/podfile.html#source\" target=\"_blank\" rel=\"noopener\">ubicaci\u00f3n<\/a> de las especificaciones al principio de su Podfile:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">source &#039;https:\/\/github.com\/Kotlin\/kotlin-cocoapods-spec.git&#039;\n\ntarget &#039;kotlin-cocoapods-xcproj&#039; do\n  \/\/ ... other Pods ...\n  pod &#039;example&#039;\nend<\/pre>\n<\/li>\n<\/ul>\n<p>Los errores de integraci\u00f3n ahora cuentan con descripciones detalladas en IntelliJ IDEA, de modo que si tiene alg\u00fan problema con su Podfile, inmediatamente obtendr\u00e1 informaci\u00f3n sobre c\u00f3mo resolverlo.<\/p>\n<p>Eche un vistazo a la rama <code>withXcproject<\/code> de la <a href=\"https:\/\/github.com\/Kotlin\/kotlin-with-cocoapods-sample\" target=\"_blank\" rel=\"noopener\">demostraci\u00f3n de Kotlin con CocoaPods<\/a>. Contiene <a href=\"#updated-integration-with-xcode\">un ejemplo de integraci\u00f3n de Xcode integration<\/a> con el proyecto de Xcode existente denominado <code>kotlin-cocoapods-xcproj<\/code>.<\/p>\n<h3>Compatibilidad con bibliotecas de Xcode 12<\/h3>\n<p>Hemos a\u00f1adido compatibilidad con nuevas bibliotecas incluidas en Xcode 12. \u00a1No dude en usarlas en su c\u00f3digo Kotlin!<\/p>\n<h2>Estructura actualizada de publicaciones de bibliotecas multiplataforma<\/h2>\n<p><a name=\"updated-structure-of-multiplatform-library-publications\"><\/a><\/p>\n<p>Antes de Kotlin 1.4.20, <a href=\"https:\/\/kotlinlang.org\/docs\/reference\/mpp-publish-lib.html\" target=\"_blank\" rel=\"noopener\">las publicaciones de bibliotecas multiplataforma<\/a> inclu\u00edan publicaciones espec\u00edficas de una plataforma y una publicaci\u00f3n de metadatos. Sin embargo, no era necesario depender \u00fanicamente de la publicaci\u00f3n de metadatos, de modo que este artefacto nunca se utilizaba expl\u00edcitamente.<\/p>\n<p>A partir de Kotlin 1.4.20 ya no existe una publicaci\u00f3n de metadatos por separado. Los artefactos de metadatos ahora se incluyen en la publicaci\u00f3n ra\u00edz, que sirve para toda la biblioteca y se resuelve autom\u00e1ticamente en los artefactos espec\u00edficos de cada plataforma al a\u00f1adirse como dependencia al conjunto de fuentes com\u00fan.<\/p>\n<p>Tenga en cuenta que no tiene que a\u00f1adir un artefacto vac\u00edo sin un clasificador al m\u00f3dulo ra\u00edz de su biblioteca para cumplir los requisitos de repositorios como Maven Central, puesto que esto dar\u00eda lugar a un conflicto con los artefactos de metadatos que ahora se incluyen en este m\u00f3dulo.<\/p>\n<h3>Compatibilidad con bibliotecas publicadas en 1.4.20<\/h3>\n<p>Si ha habilitado la <a href=\"https:\/\/kotlinlang.org\/docs\/reference\/mpp-share-on-platforms.html#share-code-on-similar-platforms\" target=\"_blank\" rel=\"noopener\">compatibilidad con estructura de proyecto jer\u00e1rquica<\/a> y desea utilizar una biblioteca multiplataforma que se public\u00f3 con dicha compatibilidad en Kotlin 1.4.20 o posterior, tambi\u00e9n tendr\u00e1 que actualizar Kotlin en su proyecto a la versi\u00f3n 1.4.20 o posterior.<\/p>\n<p>Si es el autor de una biblioteca y publica su biblioteca multiplataforma en Kotlin 1.4.20 o posterior con compatibilidad con estructura de proyecto jer\u00e1rquica, recuerde que los usuarios con versiones anteriores de Kotlin que tambi\u00e9n tengan habilitada la compatibilidad con estructura de proyecto jer\u00e1rquica no podr\u00e1n utilizar su biblioteca. Tendr\u00e1n que actualizar Kotlin a 1.4.20 o posterior.<\/p>\n<p>No obstante, si usted o los usuarios de su biblioteca no habilitan la compatibilidad con estructura de proyecto jer\u00e1rquica, quienes utilicen versiones anteriores de Kotlin todav\u00eda podr\u00e1n usar su biblioteca.<\/p>\n<p>Obtenga m\u00e1s informaci\u00f3n sobre c\u00f3mo <a href=\"https:\/\/kotlinlang.org\/docs\/reference\/mpp-publish-lib.html\" target=\"_blank\" rel=\"noopener\">publicar una biblioteca multiplataforma<\/a>.<\/p>\n<h2>Cambios en la biblioteca est\u00e1ndar<\/h2>\n<p><a name=\"standard-library-changes\"><\/a><\/p>\n<h3>Extensiones para java.nio.file.Path<\/h3>\n<p>A partir de 1.4.20, la biblioteca est\u00e1ndar ofrece extensiones experimentales para <code>java.nio.file.Path<\/code>.<\/p>\n<p>Trabajar con la API de archivo de JVM de un modo idiom\u00e1tico con Kotlin es ahora similar a trabajar con extensiones <code>java.io.File<\/code> desde el paquete <code>kotlin.io<\/code>. Ya no es necesario llamar a m\u00e9todos est\u00e1ticos de <code>Files<\/code>, puesto que la mayor\u00eda de ellos est\u00e1n ahora disponibles como extensiones en el tipo <code>Path<\/code>.<\/p>\n<p>Las extensiones se encuentran en el paquete <code>kotlin.io.path<\/code>. Como el propio <code>Path<\/code> est\u00e1 disponible en JDK 7 y posteriores, las extensiones se sit\u00faan en el m\u00f3dulo <code>kotlin-stdlib-jdk7<\/code>. Para utilizarlas, tiene que elegir la anotaci\u00f3n experimental <code>ExperimentalPathApi<\/code>.<\/p>\n<pre class=\"kotlin-code\" data-highlight-only=\"true\" theme=\"idea\" indent=\"4\" style=\"visibility: hidden; padding: 36px 0;\"> \/\/ construct path with the div (\/) operator val baseDir = Path(&quot;\/base&quot;) val subDir = baseDir \/ &quot;subdirectory&quot;\r\n\r\n\/\/ list files in a directory val kotlinFiles: List&lt;Path&gt; = Path(&quot;\/home\/user&quot;).listDirectoryEntries(&quot;*.kt&quot;) ``` <\/pre>\n<p>Deseamos agradecer especialmente a nuestro colaborador <a href=\"https:\/\/github.com\/ajalt\" target=\"_blank\" rel=\"noopener\">AJ Alt<\/a> por nos enviar la solicitud de incorporaci\u00f3n de cambios inicial con estas extensiones.<\/p>\n<h3>Rendimiento mejorado de la funci\u00f3n <code>String.replace<\/code><\/h3>\n<p>Siempre nos encanta que la comunidad de Kotlin nos sugiera mejoras, y el siguiente es uno de esos casos. En esta versi\u00f3n, hemos cambiado la implementaci\u00f3n de la funci\u00f3n <code>String.replace()<\/code>.<\/p>\n<p>La variante que distingue entre may\u00fasculas y min\u00fasculas utiliza un bucle de sustituci\u00f3n manual basado en <code> indexOf <\/code>, mientras que la que no distingue entre may\u00fasculas y min\u00fasculas utiliza la combinaci\u00f3n de expresiones regulares.<\/p>\n<p>Esta mejora acelera la ejecuci\u00f3n de la funci\u00f3n en ciertos casos.<\/p>\n<h2>Las Kotlin Android Extensions han quedado obsoletas<\/h2>\n<p><a name=\"deprecation-of-kotlin-android-extensions\"><\/a><\/p>\n<p>Desde que creamos las Kotlin Android Extensiones, han desempe\u00f1ado un papel incre\u00edble en el aumento de la popularidad de Kotlin en el ecosistema Android. Con estas extensiones, dimos a los desarrolladores herramientas pr\u00e1cticas y eficientes para reducir el c\u00f3digo reutilizable:<\/p>\n<ul>\n<li>Vistas sint\u00e9ticas (<code>kotlinx.android.synthetics<\/code>) para la interacci\u00f3n con la IU.<\/li>\n<li>Generador de implementaciones <code>Parcelable<\/code> (<code>@Parcelize<\/code>) para pasar objetos como <code>Parcel<\/code>.<\/li>\n<\/ul>\n<p>Al principio pensamos en a\u00f1adir m\u00e1s componentes a <code>kotlin-android-extensions<\/code>. Pero no lo hicimos, y hemos recibido incluso <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KT-25280\" target=\"_blank\" rel=\"noopener\">solicitudes de usuarios<\/a> para que dividamos el complemento en partes independientes.<\/p>\n<p>Por otro lado, el ecosistema Android no deja de evolucionar, y los desarrolladores van obteniendo nuevas herramientas que les facilitan el trabajo. Algunas de las lagunas que abordaba Kotlin Android Extensions ahora est\u00e1n resueltas con mecanismos nativos de Google. Por ejemplo, con respecto a la sintaxis concisa para la interacci\u00f3n con la IU, ahora existe Android Jetpack, que dispone de <a href=\"https:\/\/developer.android.com\/topic\/libraries\/view-binding\" target=\"_blank\" rel=\"noopener\">vinculaci\u00f3n de vistas<\/a>, que sustituye a <code>findViewById<\/code>, como la sintetizaci\u00f3n de Kotlin.<\/p>\n<p>Debido a estos dos motivos, hemos decidido retirar la sintetizaci\u00f3n en favor de la vinculaci\u00f3n de vistas, y pasar el generador de implementaciones Parcelable a un complemento por separado.<\/p>\n<p>En 1.4.20, hemos extra\u00eddo el generador de implementaciones Parcelable de <code>kotlin-android-extensions<\/code> y hemos iniciado el ciclo de anulaci\u00f3n del resto, que actualmente es solo sintetizaci\u00f3n. Por ahora, continuar\u00e1n funcionando con un aviso de que van a quedar en desuso. M\u00e1s adelante, tendr\u00e1 que cambiar su proyecto a otra soluci\u00f3n. Estas son las <a href=\"https:\/\/goo.gle\/kotlin-android-extensions-deprecation\" target=\"_blank\" rel=\"noopener\">instrucciones<\/a> para migrar proyectos de Android de la sintetizaci\u00f3n a la vinculaci\u00f3n de vistas.<\/p>\n<p>El generador de implementaciones Parcelable ahora est\u00e1 disponible en el nuevo complemento <a href=\"https:\/\/developer.android.com\/kotlin\/parcelize\" target=\"_blank\" rel=\"noopener\"><code>kotlin-parcelize<\/code><\/a>. Use este complemento en lugar de <code>kotlin-android-extensions<\/code>, o comb\u00ednelos si decide seguir utilizando la sintetizaci\u00f3n. La anotaci\u00f3n <code>@Parcelize<\/code> se traslada al paquete <code>kotlinx.parcelize<\/code>.<\/p>\n<h2>C\u00f3mo actualizar<\/h2>\n<p><a name=\"how-to-update\"><\/a><\/p>\n<p>Antes de actualizar sus proyectos a la versi\u00f3n m\u00e1s reciente de Kotlin, puede probar el nuevo lenguaje y las funcionalidades de biblioteca est\u00e1ndar online en <a href=\"http:\/\/play.kotl.in\/\" target=\"_blank\" rel=\"noopener\">play.kotl.in<\/a>.<\/p>\n<p>En IntelliJ IDEA y Android Studio, puede actualizar el complemento de Kotlin a la versi\u00f3n 1.4.20; descubra c\u00f3mo hacerlo <a href=\"https:\/\/kotlinlang.org\/releases.html#updating-to-a-new-release\" target=\"_blank\" rel=\"noopener\">aqu\u00ed<\/a>.<\/p>\n<p>Si desea trabajar en proyectos existentes que se crearon con versiones anteriores de Kotlin, utilice la versi\u00f3n <code>1.4.20<\/code> de Kotlin en la configuraci\u00f3n de su proyecto. Para obtener m\u00e1s informaci\u00f3n, vea los documentos <a href=\"http:\/\/kotlinlang.org\/docs\/reference\/using-gradle.html\" target=\"_blank\" rel=\"noopener\">para Gradle<\/a> y <a href=\"https:\/\/kotlinlang.org\/docs\/reference\/using-maven.html\" target=\"_blank\" rel=\"noopener\">para Maven<\/a>.<\/p>\n<p>Puede descargar el compilador de l\u00ednea de comando desde la <a href=\"https:\/\/github.com\/JetBrains\/kotlin\/releases\/tag\/v1.4.20\" target=\"_blank\" rel=\"noopener\">p\u00e1gina de lanzamiento de GitHub<\/a>.<\/p>\n<p>Puede usar las siguientes versiones de las bibliotecas con esta versi\u00f3n:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/Kotlin\/kotlinx.atomicfu\" target=\"_blank\" rel=\"noopener\">kotlinx.atomicfu<\/a> versi\u00f3n <a href=\"https:\/\/bintray.com\/kotlin\/kotlinx\/kotlinx.atomicfu\/0.14.4\" target=\"_blank\" rel=\"noopener\">0.14.4<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Kotlin\/kotlinx.coroutines\" target=\"_blank\" rel=\"noopener\">kotlinx.coroutines<\/a> versi\u00f3n <a href=\"https:\/\/bintray.com\/kotlin\/kotlinx\/kotlinx.coroutines\/1.4.1\" target=\"_blank\" rel=\"noopener\">1.4.1<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Kotlin\/kotlinx.serialization\" target=\"_blank\" rel=\"noopener\">kotlinx.serialization<\/a> versi\u00f3n <a href=\"https:\/\/bintray.com\/kotlin\/kotlinx\/kotlinx.serialization.runtime\/1.0.1\" target=\"_blank\" rel=\"noopener\">1.0.1<\/a><\/li>\n<li><a href=\"https:\/\/ktor.io\/\" target=\"_blank\" rel=\"noopener\">ktor<\/a> versi\u00f3n <a href=\"https:\/\/bintray.com\/kotlin\/ktor\/ktor\/1.4.1\" target=\"_blank\" rel=\"noopener\">1.4.1<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Kotlin\/kotlinx.html\" target=\"_blank\" rel=\"noopener\">kotlinx.html<\/a> versi\u00f3n <a href=\"https:\/\/github.com\/Kotlin\/kotlinx.html\/releases\/tag\/0.7.2\" target=\"_blank\" rel=\"noopener\">0.7.2<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Kotlin\/kotlinx-nodejs\" target=\"_blank\" rel=\"noopener\">kotlinx-nodejs<\/a> versi\u00f3n <a href=\"https:\/\/bintray.com\/kotlin\/kotlinx\/kotlinx.nodejs\/0.0.6\" target=\"_blank\" rel=\"noopener\">0.0.6<\/a><\/li>\n<\/ul>\n<p>Las versiones de las bibliotecas de <code>kotlin-wrappers<\/code> (<code>kotlin-react<\/code> etc.) se pueden encontrar en el <a href=\"https:\/\/github.com\/JetBrains\/kotlin-wrappers\" target=\"_blank\" rel=\"noopener\">repositorio correspondiente<\/a>.<\/p>\n<p>Los detalles del lanzamiento y la lista de bibliotecas compatibles tambi\u00e9n est\u00e1n disponibles <a href=\"https:\/\/kotlinlang.org\/releases.html#release-details\" target=\"_blank\" rel=\"noopener\">aqu\u00ed<\/a>.<\/p>\n<p>Si encuentra alg\u00fan problema con la nueva versi\u00f3n, encontrar\u00e1 ayuda en <a href=\"http:\/\/kotlinlang.slack.com\/\" target=\"_blank\" rel=\"noopener\">Slack<\/a> (obtenga una invitaci\u00f3n <a href=\"https:\/\/surveys.jetbrains.com\/s3\/kotlin-slack-sign-up?_ga=2.134077326.1218289669.1605167163-154294388.1603171954\" target=\"_blank\" rel=\"noopener\">aqu\u00ed<\/a>) e informe acerca de las incidencias en nuestro <a href=\"https:\/\/youtrack.jetbrains.com\/issues\/KT\" target=\"_blank\" rel=\"noopener\">YouTrack<\/a>.<\/p>\n<h2>Colaboradores externos<\/h2>\n<p><a name=\"external-contributors\"><\/a><\/p>\n<p>Nos gustar\u00eda agradecer a todos los contribuidores externos cuyas solicitudes de incorporaci\u00f3n de cambios se han incluido en esta versi\u00f3n:<\/p>\n<p><a href=\"https:\/\/github.com\/jsjeon\" target=\"_blank\" rel=\"noopener\">Jinseong Jeon<\/a> <a href=\"https:\/\/github.com\/t-kameyama\" target=\"_blank\" rel=\"noopener\">Toshiaki Kameyama<\/a> <a href=\"https:\/\/github.com\/sfs\" target=\"_blank\" rel=\"noopener\">Steven Sch\u00e4fer<\/a> <a href=\"https:\/\/github.com\/madsager\" target=\"_blank\" rel=\"noopener\">Mads Ager<\/a> <a href=\"https:\/\/github.com\/punzki\" target=\"_blank\" rel=\"noopener\">Mark Punzalan<\/a> <a href=\"https:\/\/github.com\/gavra0\" target=\"_blank\" rel=\"noopener\">Ivan Gavrilovic<\/a> <a href=\"https:\/\/github.com\/pyos\" target=\"_blank\" rel=\"noopener\">pyos<\/a> <a href=\"https:\/\/github.com\/jimgoog\" target=\"_blank\" rel=\"noopener\">Jim Sproch<\/a> <a href=\"https:\/\/github.com\/kandersen\" target=\"_blank\" rel=\"noopener\">Kristoffer Andersen<\/a> <a href=\"https:\/\/github.com\/aleksandrina-streltsova\" target=\"_blank\" rel=\"noopener\">Aleksandrina Streltsova<\/a> <a href=\"https:\/\/github.com\/cketti\" target=\"_blank\" rel=\"noopener\">cketti<\/a> <a href=\"https:\/\/github.com\/kvirolainen\" target=\"_blank\" rel=\"noopener\">Konstantin Virolainen<\/a> <a href=\"https:\/\/github.com\/ajalt\" target=\"_blank\" rel=\"noopener\">AJ Alt<\/a> <a href=\"https:\/\/github.com\/tunedal\" target=\"_blank\" rel=\"noopener\">Henrik Tunedal<\/a> <a href=\"https:\/\/github.com\/juan-chen\" target=\"_blank\" rel=\"noopener\">Juan Chen<\/a> <a href=\"https:\/\/github.com\/kotlinisland\" target=\"_blank\" rel=\"noopener\">KotlinIsland<\/a>, <a href=\"https:\/\/github.com\/valery1707\" target=\"_blank\" rel=\"noopener\">Valeriy Vyrva<\/a> <a href=\"https:\/\/github.com\/achmyr\" target=\"_blank\" rel=\"noopener\">Alex Chmyr<\/a> <a href=\"https:\/\/github.com\/cdracm\" target=\"_blank\" rel=\"noopener\">Alexey Kudravtsev<\/a> <a href=\"https:\/\/github.com\/mano7onam\" target=\"_blank\" rel=\"noopener\">Andrey Matveev<\/a> <a href=\"https:\/\/github.com\/liutikas\" target=\"_blank\" rel=\"noopener\">Aurimas Liutikas<\/a> <a href=\"https:\/\/github.com\/Dattish\" target=\"_blank\" rel=\"noopener\">Dat Trieu<\/a> <a href=\"https:\/\/github.com\/devbridie\" target=\"_blank\" rel=\"noopener\">Dereck Bridie<\/a> <a href=\"https:\/\/github.com\/efemoney\" target=\"_blank\" rel=\"noopener\">Efeturi Money<\/a> <a href=\"https:\/\/github.com\/elijahverdoorn\" target=\"_blank\" rel=\"noopener\">Elijah Verdoorn<\/a> <a href=\"https:\/\/github.com\/43851243+enteerman\" target=\"_blank\" rel=\"noopener\">Enteerman<\/a> <a href=\"https:\/\/github.com\/fee1-dead\" target=\"_blank\" rel=\"noopener\">fee1-dead<\/a> <a href=\"https:\/\/github.com\/fvasco\" target=\"_blank\" rel=\"noopener\">Francesco Vasco<\/a> <a href=\"https:\/\/github.com\/duckladydinh\" target=\"_blank\" rel=\"noopener\">Gia Thuan Lam<\/a> <a href=\"https:\/\/github.com\/gdarmont\" target=\"_blank\" rel=\"noopener\">Guillaume Darmont<\/a> <a href=\"https:\/\/github.com\/JakeWharton\" target=\"_blank\" rel=\"noopener\">Jake Wharton<\/a> <a href=\"https:\/\/github.com\/juliankotrba\" target=\"_blank\" rel=\"noopener\">Julian Kotrba<\/a> <a href=\"https:\/\/github.com\/kevin1e100\" target=\"_blank\" rel=\"noopener\">Kevin Bierhoff<\/a> <a href=\"https:\/\/github.com\/gharrma\" target=\"_blank\" rel=\"noopener\">Matthew Gharrity<\/a> <a href=\"https:\/\/github.com\/Matts966\" target=\"_blank\" rel=\"noopener\">Matts966<\/a> <a href=\"https:\/\/github.com\/rsauciuc\" target=\"_blank\" rel=\"noopener\">Raluca Sauciuc<\/a> <a href=\"https:\/\/github.com\/rnett\" target=\"_blank\" rel=\"noopener\">Ryan Nett<\/a> <a href=\"https:\/\/github.com\/pocmo\" target=\"_blank\" rel=\"noopener\">Sebastian Kaspari<\/a> <a href=\"https:\/\/github.com\/develar\" target=\"_blank\" rel=\"noopener\">Vladimir Krivosheev<\/a> <a href=\"https:\/\/github.com\/n-p-s\" target=\"_blank\" rel=\"noopener\">n-p-s<\/a> <a href=\"https:\/\/github.com\/pavlospt\" target=\"_blank\" rel=\"noopener\">Pavlos-Petros Tournaris<\/a> <a href=\"https:\/\/github.com\/rbares\" target=\"_blank\" rel=\"noopener\">Robert Bares<\/a> <a href=\"https:\/\/github.com\/shiraji\" target=\"_blank\" rel=\"noopener\">Yoshinori Isogai<\/a> <a href=\"https:\/\/github.com\/zekehul\" target=\"_blank\" rel=\"noopener\">Kris<\/a> <a href=\"https:\/\/github.com\/bodin\" target=\"_blank\" rel=\"noopener\">Derek Bodin<\/a> <a href=\"https:\/\/github.com\/Lurker2k\" target=\"_blank\" rel=\"noopener\">Dominik Wuttke<\/a> <a href=\"https:\/\/github.com\/samofcorinth\" target=\"_blank\" rel=\"noopener\">Sam Wang<\/a> <a href=\"https:\/\/github.com\/uzilan\" target=\"_blank\" rel=\"noopener\">Uzi Landsmann<\/a> <a href=\"https:\/\/github.com\/yurano\" target=\"_blank\" rel=\"noopener\">Yuya Urano<\/a> Norbert Nogacki Alexandre Juca<\/p>\n","protected":false},"author":1086,"featured_media":95158,"comment_status":"closed","ping_status":"closed","template":"","categories":[907],"tags":[477],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/kotlin\/99828"}],"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=99828"}],"version-history":[{"count":1,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/kotlin\/99828\/revisions"}],"predecessor-version":[{"id":99831,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/kotlin\/99828\/revisions\/99831"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media\/95158"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media?parent=99828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/categories?post=99828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/tags?post=99828"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/cross-post-tag?post=99828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}