Kotlin, primeros pasos

0
6352

En este tutorial vamos a dar nuestros primeros pasos con el lenguaje de programación Kotlin, para ello veremos qué necesitamos para poder empezar a hacer nuestros primeros programas mediante ejemplos sencillos.

1. Introducción

Kotlin es un lenguaje de programación fuertemente tipado que se ejecuta principalmente sobre la JVM (Java Virtual Machine), y digo «principalmente» porque también es posible compilarlo a JavaScript o incluso a código nativo, pero por ahora nos vamos a centrar en la JVM y sus capacidades de interoperabilidad con librerías o cualquier código escrito en Java.

Es un lenguaje creado por JetBrains (sí, sí, los creadores de los conocidos IDE de desarrollo IntelliJ, PyCharm, WebStorm, AppCode…​) hace algún tiempo, pero parece que ha saltado de nuevo a la palestra con el anuncio por parte de Google de considerarlo lenguaje de primer nivel para el desarrollo de Android y, por tanto, darle soporte directo.

Esto es muy buena noticia y va a ayudar a garantizar la vida y evolución del lenguaje, por lo que puede ser un buen momento para echarle a un vistazo al lenguaje, ya que este de verdad tiene cosas muy interesantes, especialmente para los que venimos de Java o ya usamos la JVM.

  • Es un lenguaje fuertemente tipado. Llamadme viejuno y para gustos los colores, pero para mí esto es fundamental en un lenguaje. El hecho de que el propio compilador nos detecte errores de escritura en un tiempo anterior al de ejecución me parece maravilloso, esto sin contar con que las herramientas disponibles son mucho más potentes que en un lenguaje no tipado.

  • Interoperabilidad con Java y la JVM en general. Una cosa que han hecho muy bien es cómo puedes combinar Kotlin con tus programas o librerías ya escritos en Java. Desde tu nuevo código escrito en Kotlin puedes llamar directamente a cualquier clase de Java, y al revés también, desde Java puedes llamar a código escrito en Kotlin. Esto nos permite reutilizar el gran ecosistema al que ya estamos acostumbrados en Java.

  • ¡Compila directamente a bytecode! No penséis cosas raras de que transforma el código a Java y luego lo compila con javac. No, no, no, tiene compilador propio y genera directamente bytecode de la JVM, sin pasos intermedios.

A nivel de lenguaje nos vamos a encontrar con todo lo que tiene Java y muchas características más que van a facilitarnos mucho la vida a la hora de hacer nuestras aplicaciones. No voy a contarlas todas, ya que la idea de este tutorial no es enseñar Kotlin, y para ello os recomiendo la propia guía de referencia de Kotlin, muy completa, clara y con ejemplos. Pero podemos destacar:

  • Funciones de extensión (mixins). Esto no existe en Java y para hacer algo parecido hay que montar un arco de iglesia. Muy interesante para no abusar de la herencia, que es una relación que acopla mucho a los participantes.

  • Las funciones son elementos de primer nivel. Sí, tendremos lambdas por todos lados, y sin llegar a ser un lenguaje funcional completo como Clojure o Scala, vamos a poder disfrutar de muchas cositas.

  • Todo es una expresión, esto quiere decir que podemos hacer cosas como poner un if a la derecha de un = (asignación).

  • Y muchas otras cosas como:

    • Control de nulos en tiempo de compilación (The Billion Dollar Mistake).

    • Inferencia de tipos.

    • Sobrecarga de operadores (+, -, [], ==, etc.).

    • Rangos.

    • Patrones implementados directamente en el lenguaje como el Builder o el Delegate.

    • Azúcar sintáctico que nos va a permitir la construcción de DSLs.

    • Coroutines, todavía en experimental pero una buena ayuda para la programación concurrente. Según los autores: «Coroutines provide a way to avoid blocking a thread and replace it with a cheaper and more controllable operation: suspension of a coroutine.»

    • …​

Sólo con esta lista parcial espero haber picado tu curiosidad para, por lo menos, echar un ojo a la guía de referencia de Kotlin.

Además, si queréis hacer pruebas o ver ejemplos, lo podéis hacer directamente desde el navegador en https://try.kotlinlang.org.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15» (2.5 GHz Intel i7, 16GB 1600 Mhz DDR3, 500GB Flash Storage).

  • AMD Radeon R9 M370X

  • Sistema Operativo: macOS Sierra 10.12.5

  • JVM 1.8.0_121 (Oracle Corporation 25.121-b13)

  • Kotlin 1.1.3

  • Gradle 4.0

3. Instalación de Kotlin

Lo mejor de todo es que Kotlin no necesita instalación.

Por supuesto Kotlin tiene un compilador de línea de comandos, pero no va a ser necesaria su instalación ya que normalmente vamos a trabajar con Maven o con Gradle, en concreto en este tutorial usaremos Gradle. En cualquier caso, si tenéis curiosidad podéis encontrar más información en https://kotlinlang.org/docs/tutorials/command-line.html

Así, para preparar la estructura de nuestro primer proyecto, ejecutaremos:

$ mkdir kotlin-tutorial ; cd kotlin-tutorial
$ gradle init
$ mkdir -p src/main/kotlin
$ mkdir -p src/test/kotlin
                

Para que Gradle sea capaz de compilar Kotlin sobreescribimos todo el contenido del fichero build.gradle (veréis que el contenido está totalmente comentado y es sólo un ejemplo que podéis borrar con tranquilidad) con:

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.1.3'
}

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8

    kotlinOptions {
        jvmTarget = '1.8'
    }
}

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.jetbrains.kotlin:kotlin-stdlib-jre8'
}
                

Aquí destacamos:

  • línea 2 – declaramos el plugin de Kotlin. Esta es la nueva forma de declarar los plugins en Gradle y Kotlin ya la soporta.

  • líneas 5 a 12 – estamos indicando la configuración para todas las tareas de tipo compilación de Kotlin. Esto es conveniente hacerlo así ya que realmente puede haber varias tareas de este tipo, por ejemplo para compilar el código, para compilar el código de los tests, para compilar el código de producción, el de desarrollo…​

  • línea 10 – vemos cómo le estamos indicando al compilador de Kotlin que vamos a usar una JVM 1.8. Esto sirve para que el compilador haga ciertas optimizaciones y le saque más partido a la JVM. A día de hoy, si no especificamos nada, el valor por defecto será 1.6.

Ahora vamos a crear nuestro primer código Kotlin y, como no podía ser de otra forma, empezaremos por nuestro querido «Hola, mundo». Para ello creamos el fichero src/main/kotlin/App.kt con el siguiente contenido:

fun main(args: Array<String>) {
    println("Hello, world!")
}
                

Se ve cómo es simplemente el punto de entrada de la aplicación, donde nos entra un array con los argumentos de la línea de comandos y simplemente escribimos un mensaje por consola. Cabe destacar cómo hemos escrito la función sin necesidad de que esta esté dentro de una clase, y no como en Java, donde sí tenemos esa restricción.

Para ver que todo funciona correctamente, ejecutamos en la línea de comandos:

$ gradle build
                

Donde deberíamos ver algo similar a:

Gradle Kotlin build success

4. Añadiendo soporte para tests

Sólo con el punto anterior ya podríamos empezar a hacer aplicaciones con Kotlin, pero ya sabéis que soy muy fan de los tests y que no entiendo el desarrollo sin ellos, así que vamos a modificar un poco el fichero build.gradle para añadir soporte para JUnit 5.

Añadir soporte para JUnit 4 hubiera sido cuestión de añadir una dependencia, mientras que el soporte para JUnit 5 nos va a costar un poquito más (no es culpa de Kotlin, sino del propio soporte de JUnit 5), pero quiero hacer este ejemplo para que veáis cómo podemos usar Kotlin con las últimas versiones de nuestras librerías Java sin ningún problema.

Primero vamos a añadir al principio del fichero las siguientes líneas para dar de alta el plugin de Gradle de JUnit 5 (como vemos, todavía no soporta el nuevo DSL de Gradle para la definición de plugins):

buildscript {
    ext {
        junitPlatformVersion = '1.0.0-M4'
        junitJupiterVersion = '5.0.0-M4'
        junitVintageVersion = '4.12.0-M4'
    }

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.junit.platform:junit-platform-gradle-plugin:${junitPlatformVersion}"
    }
}
                

Ahora aplicamos el plugin, para ello justo después de la sección de plugins { …​ } que tenemos de antes, añadimos la línea:

apply plugin: 'org.junit.platform.gradle.plugin'
                

Y por último, dentro de la sección de dependencias, añadimos las necesarias para poder escribir los tests:

dependencies {
    ...
    testCompile 'org.jetbrains.kotlin:kotlin-test'
    testCompile 'org.jetbrains.kotlin:kotlin-test-junit'

    testCompile "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}"
    testRuntime "org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}"
    testRuntime "org.junit.vintage:junit-vintage-engine:${junitVintageVersion}"
}
                

Aquí podemos destacar:

  • línea 3 – Añadimos una librería de Kotlin que nos proporciona funciones de aserción (assertEquals…​) más al estilo de Kotlin. Esto no es estrictamente necesario y podemos usar directamente las de JUnit, pero nos va a facilitar la escritura de los tests.

  • línea 4 – Es otra librería de Kotlin que da soporte a la librería anterior para integrarla con el ciclo de JUnit, de forma que todo el reporte de errores, etc., sea a través de JUnit.

  • líneas de la 6 a la 8 – Son simplemente las dependencias de JUnit 5 que usaríamos en cualquier caso (sea Kotlin o Java).

Podemos mencionar también cómo en el caso de las dependencias de las líneas 3 y 4 no hemos puesto versión, esto es posible gracias a que el propio plugin de Kotlin las va a proporcionar en función de la versión de Kotlin que estamos usando.

Os pongo el fichero completo para que sea más fácil verlo:

buildscript {
    ext {
        junitPlatformVersion = '1.0.0-M4'
        junitJupiterVersion = '5.0.0-M4'
        junitVintageVersion = '4.12.0-M4'
    }

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.junit.platform:junit-platform-gradle-plugin:${junitPlatformVersion}"
    }
}

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.1.3'
}

apply plugin: 'org.junit.platform.gradle.plugin'

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8

    kotlinOptions {
        jvmTarget = '1.8'
    }
}

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.jetbrains.kotlin:kotlin-stdlib-jre8'

    testCompile 'org.jetbrains.kotlin:kotlin-test'
    testCompile 'org.jetbrains.kotlin:kotlin-test-junit'

    testCompile "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}"
    testRuntime "org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}"
    testRuntime "org.junit.vintage:junit-vintage-engine:${junitVintageVersion}"
}
                

Ya podemos escribir tests en Kotlin usando JUnit 5. Podemos hacer la prueba creando el fichero src/test/kotlin/AppTest.kt con el contenido:

import org.junit.jupiter.api.Test
import kotlin.test.assertEquals

class AppTest {

    @Test
    fun `addition is correct`() {
        assertEquals(4, 2 + 2)
    }
}
                

Podemos destacar:

  • línea 1 – estamos usando la anotación de JUnit 5.

  • línea 2 – estamos usando las aserciones de la librería de Kotlin.

  • línea 7 – vemos cómo el acento inverso ` es un carácter válido para el nombre de un método y esto nos permite poner espacios, con lo que conseguimos métodos de tests más legibles (no sería recomendable para los métodos de las clases de producción pero sí muy conveniente para los métodos de test).

Si ahora ejecutamos (el clean no es necesario pero lo ponemos para forzar una compilación completa):

$ gradle clean build
                

deberíamos ver algo similar a:

Gradle Kotlin build tests success

Si ejecutamos los tests desde el IntelliJ, veremos algo como:

Kotlin IntelliJ tests

Donde podemos apreciar la ventaja de los nombres.

5. Conclusiones

Si solemos trabajar con Java, o en general con la JVM, empezar con Kotlin es muy sencillo, ya que la barrera de entrada, por lo menos para jugar un poco, es prácticamente inexistente.

Además, ya tenemos cantidad de herramientas que lo soportan, incluyendo los tres grandes IDEs a día de hoy: Eclipse, Netbeans y, por supuesto, IntelliJ y Android Studio.

Otra buena referencia es este site donde podréis encontrar cantidad de información y recursos: Kotlin is awesome!

¿Kotlin va a sustituir a Java? Sólo el tiempo lo dirá, pero lo que está claro es que trae cantidad de cosas útiles, que está evolucionando muy rápido, y que ahora también tiene el apoyo de Google. Todo esto sumado a la facilidad para mezclarlo con nuestro código y librerías existentes lo convierte en una opción más que viable y atractiva. Más vale que Java se ande con ojo y se dé un poco de vidilla si no quiere quedarse en la cuenta.

Eso sí, ¡larga vida a la JVM!

6. Sobre el autor

Alejandro Pérez García (@alejandropgarci)
Ingeniero en Informática (especialidad de Ingeniería del Software) y Certified ScrumMaster

Socio fundador de Autentia Real Business Solutions S.L. – «Soporte a Desarrollo»

Socio fundador de ThE Audience Megaphone System, S.L. – TEAMS – «Todo el potencial de tus grupos de influencia a tu alcance»

Alejandro es socio fundador de Autentia y nuestro experto en Java EE, Linux y optimización de aplicaciones empresariales. Ingeniero en Informática y Certified ScrumMaster. Seguir @alejandropgarci Si te gusta lo que ves, puedes contratarle para darte ayuda con soporte experto, impartir cursos presenciales en tu empresa o para que realicemos tus proyectos como factoría (Madrid). Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad