Upgrade to Pro — share decks privately, control downloads, hide ads and more …

De Cero a Cien con Kotlin

De Cero a Cien con Kotlin

Juanjo Aguililla

November 18, 2016
Tweet

Other Decks in Programming

Transcript

  1. A propósito de Juanjo Desarrollador Java Backend (Java, Groovy, Scala

    y Kotlin) Creador del framework Open Source Hexagon Organizador de KotlinMAD Trabajando en azampar.co • Github: http://github.com/jaguililla • Twitter: http://twitter.com/jaguililla • Linkedin: http://linkedin.com/in/jaguililla
  2. Origen y objetivo de Kotlin JetBrains desarrolló Kotlin para cubrir

    sus propias necesidades: • Mantener una gran cantidad de código Java en producción • En distintas plataformas (Web y Desktop principalmente) • Eliminar los problemas más comunes en sus productos. Ej: NPEs Diseñado para facilitar el desarrollo de herramientas (ya cuenta con un buen compilador y un REPL) Fue liberado como Open Source bajo licencia Apache 2 en Github La versión 1.0 se liberó en febrero de 2016
  3. ADN del lenguaje Lenguaje de programación de propósito general (que

    vale para todo) Compilado a Java bytecode y JavaScript Tipado estático (permite dinámico para JavaScript) Multiparadigma: OO y FP Se puede ejecutar sobre Android, Servidores, Escritorio, Navegador y Shell
  4. Sistema de Tipos null es parte del sistema de tipos

    (como Optional). Parte del lenguaje, no de la librería Any? es la base de todos los tipos (como Object en Java) Unit es el equivalente a void en Java Nothing es utilizado por expresiones que no retornan ningún valor
  5. Estructura del código // El fichero `de0a100.kt` compila a la

    clase `com.paquete.De0a100Kt` package com.paquete // Puede estar en cualquier directorio import java.util.Date.parse as parseDate // Las definiciones pueden renombrarse // Definiciones `public` si no se indica `internal` o `private` val valPaquete = 0 // import com.paquete.valPaquete fun funPaquete() = true // En Java: com.paquete.De0a100Kt.funPaquete() // Ejecutado como `java com.paquete.De0a100Kt` fun main(args: Array<String>) { println("Hola Kotlin") }
  6. Variables y constantes val constante = true // Mira mamá...

    sin tipos //constante = false // Error de compilación var variable: String = """cadenas multilínea con sustitución de variables $constante ${2 + 2}""" // Los operadores de bits son funciones infijas val bits = 0b1 shl 1 and 0b0 // Inicializado en el primer acceso val initEnAcceso: Long by lazy { System.currentTimeMillis() }
  7. Arrays // Se pueden inicializar con un lambda val array:

    Array<Int> = Array(5) { ii -> ii } // [ 0, 1, 2, 3, 4 ] val arrayLiteral = arrayOf(1, 2, 3) // Transformar arrays en listas (y viceversa) array.toList() listOf('A', 'B', 'C').toTypedArray() val primeraPosicion = array[0] val subarray = array.slice(1..2)
  8. Manejo de valores null val entero: Int? = null //

    '?' Indica valor opcional //val error: Int = entero + 1 // Con `?:` Puedes controlar `null` de manera concisa val ok: Int = (entero ?: 0) + 1 data class Address(val street: String, val locality: String?) val address: Address? = Address("Atocha, 1", "Madrid") // Operador safe call `?.` val localidad = address?.locality ?: "Sin localidad"
  9. Funciones // Parámetros con valores por defecto fun funcion(entero: Int

    = 0, parametro: String = "defecto") = parametro + entero.toString() funcion() // Argumentos por defecto funcion(parametro = "valor") // Paso de argumentos por nombre fun procedimiento(): Unit { println("Hola") } // Unit es opcional fun matroska() { val local = 1 fun matroska1() = local }
  10. Lambdas // Bloques de código almacenados como variables val lambda

    = { a: Int, b: Int -> "$a $b" } // Se invocan como una función lambda(10, 20) // Se pueden pasar por parámetro fun higherOrderFun(p: Int, lambda: (Int) -> Int) = lambda(p) // Si es el último parámetro acepta sintaxis alternativa higherOrderFun(10, { it * 2 }) higherOrderFun(10) { it * 2 }
  11. Métodos de extensión // Añaden métodos a clases existentes //

    Útiles para ampliar librerías sin código fuente fun String.addTimestamp() = this + " " + System.currentTimeMillis() // El objeto sobre el que se aplican se llama 'receiver' // Se puede especificar un `receiver` nullable fun String?.addNullTimestamp() = this ?: "Esto es null" + " " + System.currentTimeMillis() "hola".addTimestamp() null.addNullTimestamp()
  12. Herencia interface Interfaz { val valor: Int // Los interfaces

    pueden contener variables fun funcion(): String } abstract class ClaseAbstracta { abstract fun funcion(): String } // Las clases son ‘final’ por defecto // Los parámetros del constructor principal se definen en la clase open class ClaseBase(val campo: String = "foo")
  13. Clases // param solo es visible en la inicialización class

    Clase(param: String, val propiedad: Int = 0) : ClaseBase(param), Interfaz { var propiedad2 = param override val valor = 42 init { println(param) } constructor() : this("parametro", 99) fun metodo() = "resultado" override fun funcion() = "implementada" } val c = Clase("parametro") // No se utiliza 'new'
  14. Propiedades class PersonV1 { var age: Int = 0 }

    // Field es la variable final (p. reservada) class PersonV2 { var age: Int = 0 get() = field set(value) { require(value < 18) field = value } } // Compila con `PersonV1` y `PersonV2` val p = PersonV2() // Con `PersonV2` lanza una excepción p.age = 8
  15. Data Clases // DTO inmutable (sobrescribe `equals`, `hashcode` y `toString`

    // Pueden implementar interfaces, no pueden heredar clases data class Person(val name: String, val age: Int = 0) val alfredo = Person("Alfredo Lambda", 61) // Copiar instancia cambiando campos val alfredoLanda = alfredo.copy( name = "Alfredo Landa", age = 62 )
  16. When val v: Any = 0 // Cast automático when

    (v) { is String -> println (v.substring(1..2)) in 1..9 -> println("Int") !in 1..9 -> println("Fuera de rango") 0 -> println ("Zero") else -> println ("Nada de lo anterior") } // Se puede utilizar como un if-elseif // más limpio when { (v as Int > 10) -> println("+10") "" is String -> println ("true") else -> println ("Nunca se ejecuta") }
  17. Listas // No son modificables val lista = listOf(0, 1,

    2) assert(lista[0] == 0) assert(1 in lista) assert(3 !in lista) val listaM = mutableListOf(0, 1, 2)
  18. Mapas val mapa = mapOf ( "España" to "ES", "Reino

    Unido" to "UK" ) assert("España" in mapa) assert(mapa["España"] == "ES") val mapa2 = mapa + ("Italia" to "IT") val mapaM = mutableMapOf ("a" to 0, "b" to true) mapaM["a"] = 'C'
  19. Librería estándar FileReader("file.txt").use { println (readLine()) } with("String") { substring(0

    .. length - 1) } "String".let { it.substring(0 .. it.length - 1) } // Atajo de if-param-throw require(true) { "Parametro inválido" } // Atajo de if-var-throw check(true) { "Estado inválido" } // Atajo de `throw IllegalState... error("Estado invalido")
  20. Librerías de terceros Android: Anko y Android Extensions Web: Ktor,

    Wasabi, Kara, Hexagon Desktop (JavaFX) TornadoFX Testing: Spek, KotlinTest y Mockito-kotlin Inyección de dependencias: Kodein e Injekt Otros: Gradle (scripts con Kotlin en vez de Groovy) Es muy sencillo utilizar librerías escritas en Java
  21. Recursos Kotlin documentation: muy completa y precisa Kotlin koans: cuando

    los acabes conocerás el lenguaje bastante bien Blog: últimas noticias del lenguaje Slack: muy activo (tiene un canal en español) Kotlin for Android: De Antonio Leiva Kotlin in Action: Manning (MEAP) Stack Overflow