Capacitación de Kotlin para programadores 3: funciones

Este codelab es parte del curso Capacitación de Kotlin para programadores. Aprovecharás al máximo este curso si trabajas con los codelabs en secuencia. Según tus conocimientos, es posible que puedas cambiar algunas secciones. Este curso está dirigido a los programadores que conocen un lenguaje orientado a objetos y desean aprender Kotlin.

Introducción

En este codelab, crearás un programa en Kotlin y aprenderás sobre las funciones de Kotlin, incluidos los valores predeterminados de parámetros, filtros, lambdas y funciones compactas.

En lugar de compilar una sola app de muestra, las lecciones de este curso están diseñadas para aumentar tu conocimiento, pero son semiindependientes entre sí a fin de que puedas leer las secciones con las que estás familiarizado. Para vincularlos, muchos de los ejemplos usan un tema de acuario. Si deseas ver la historia completa del acuario, consulta el curso de Udacity Capacitación de Kotlin para programadores.

Conocimientos que ya deberías tener

  • Conceptos básicos de un lenguaje de programación moderno, escrito de forma estática y orientado a objetos
  • Cómo programar clases con métodos y control de excepciones en al menos un lenguaje
  • Cómo trabajar con REPL (Read-Eval-Print Loop) de Kotlin en IntelliJ IDEA
  • Conceptos básicos de Kotlin, incluidos tipos, operadores y bucles

Este codelab está dirigido a programadores que conocen un lenguaje orientado a objetos y desean obtener más información sobre Kotlin.

Qué aprenderás

  • Cómo crear un programa con una función main() y argumentos en IntelliJ IDEA
  • Cómo usar valores predeterminados y funciones compactas
  • Cómo aplicar filtros a las listas
  • Cómo crear lambdas básicas y funciones de orden superior

Actividades

  • Trabaje con el REPL para probar un poco de código.
  • Trabaja con IntelliJ IDEA para crear programas básicos de Kotlin.

En esta tarea, crearás un programa en Kotlin, obtendrás información sobre la función main() y cómo pasar argumentos a un programa desde la línea de comandos.

Quizás recuerdes la función printHello() que ingresaste en el REPL en un codelab anterior:

fun printHello() {
    println ("Hello World")
}

printHello()
⇒ Hello World

Las funciones se definen con la palabra clave fun, seguida del nombre de la función. Al igual que con otros lenguajes de programación, los paréntesis () son para argumentos de funciones, si corresponde. Las llaves {} enmarcan el código para la función. No hay un tipo de datos que se muestre para esta función, ya que no muestra nada.

Paso 1: Crea un archivo Kotlin

  1. Abre IntelliJ IDEA.
  2. En el panel Project de la izquierda de IntelliJ IDEA, se muestra la lista de archivos y carpetas de tu proyecto. Busca la carpeta src y haz clic con el botón derecho en ella en Hello Kotlin. (Ya deberías tener el proyecto Hello Kotlin del codelab anterior).
  3. Selecciona New > Kotlin File / Class.
  4. Conserva Kind como File y asígnale el nombre Hello.
  5. Haga clic en OK.

Ahora hay un archivo en la carpeta src llamado Hello.kt.

Paso 2: Agrega código y ejecuta tu programa

  1. Al igual que con otros lenguajes, la función main() de Kotlin especifica el punto de entrada para la ejecución. Cualquier argumento de la línea de comandos se pasa como un arreglo de strings.

    Escribe o pega el siguiente código en el archivo Hello.kt:
fun main(args: Array<String>) {
    println("Hello, world!")
}

Al igual que tu función printHello() anterior, esta función no tiene ninguna declaración return. Cada función de Kotlin muestra algo, incluso cuando no se especifica nada de forma explícita. Entonces, una función como esta main() muestra un tipo kotlin.Unit, que es la forma de Kotlin de decir que no tiene valor.

  1. Para ejecutar el programa, haz clic en el triángulo verde a la izquierda de la función main(). Selecciona Run 'HelloKt' en el menú.
  2. IntelliJ IDEA compila el programa y lo ejecuta. Los resultados aparecen en un panel de registro en la parte inferior, como se muestra a continuación.

Paso 3: Pasa argumentos a main()

Dado que ejecutas tu programa desde IntelliJ IDEA y no desde la línea de comandos, debes especificar cualquier argumento para el programa de una manera un poco diferente.

  1. Selecciona Run > Edit Configurations. Se abrirá la ventana Run/Debug Configurations.
  2. Escribe Kotlin! en el campo Programarguments (Argumentos del programa).
  3. Haga clic en OK.

Paso 4: Cambia el código para usar una plantilla de strings

Una plantilla de strings inserta una variable o expresión en una string, y $ especifica que parte de la string será una variable o una expresión. Las llaves {} enmarcan la expresión, si la hubiera.

  1. En Hello.kt, cambia el mensaje de saludo para usar el primer argumento que se pasa al programa, args[0], en lugar de "world".
fun main(args: Array<String>) {
    println("Hello, ${args[0]}")
}
  1. Ejecuta el programa. El resultado incluirá el argumento que especificaste.
⇒ Hello, Kotlin!

En esta tarea, aprenderás por qué casi todo tiene un valor en Kotlin y por qué es útil.

Otros lenguajes tienen sentencias, que son líneas de código que no tienen un valor. En Kotlin, casi todo es una expresión y tiene un valor, incluso si ese valor es kotlin.Unit.

  1. En Hello.kt, escribe el código en main() para asignar un println() a una variable llamada isUnit y luego imprimirlo. (println() no muestra un valor, por lo que muestra kotlin.Unit).
// Will assign kotlin.Unit
val isUnit = println("This is an expression")
println(isUnit)
  1. Ejecuta el programa. El primer elemento println() imprime la string "This is an expression". El segundo println() muestra el valor de la primera sentencia println(), es decir, kotlin.Unit.
⇒ This is an expression
kotlin.Unit
  1. Declara un val llamado temperature y, luego, inicialízalo en 10.
  2. Declara otro val llamado isHot y asigna el valor que se muestra de una declaración if/else a isHot, como se muestra en el siguiente código. Como es una expresión, puedes usar el valor de la expresión if de inmediato.
val temperature = 10
val isHot = if (temperature > 50) true else false
println(isHot)
⇒ false
  1. Usa el valor de una expresión en una plantilla de strings. Agrega un código para comprobar la temperatura a fin de determinar si un pez está a salvo o hace demasiado calor. Luego, ejecuta el programa.
val temperature = 10
val message = "The water temperature is ${ if (temperature > 50) "too warm" else "OK" }."
println(message)
⇒ The water temperature is OK.

En esta tarea, obtendrás más información sobre las funciones de Kotlin y la expresión condicional when, que es muy útil.

Paso 1: Crea algunas funciones

En este paso, reunirás parte de lo que aprendiste y crearás funciones con diferentes tipos. Puedes reemplazar el contenido de Hello.kt con este código nuevo.

  1. Escribe una función llamada feedTheFish() que llame al objeto randomDay() para obtener un día de la semana al azar. Usa una plantilla de strings a fin de imprimir una food para que los peces puedan comer ese día. Por ahora, los peces se alimentan de la misma comida todos los días.
fun feedTheFish() {
    val day = randomDay()
    val food = "pellets"
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}
  1. Escribe la función randomDay() para elegir un día aleatorio de un arreglo y mostrarlo.

La función nextInt() toma un límite de números enteros, que limita el número de Random() a 0 para que coincida con el array week.

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
            "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}
  1. Las funciones Random() y nextInt() se definen en java.util.*. En la parte superior del archivo, agrega la importación necesaria:
import java.util.*    // required import
  1. Ejecuta el programa y verifica el resultado.
⇒ Today is Tuesday and the fish eat pellets

Paso 2: Usa una expresión when

Si lo extiendes aún más, cambia el código para elegir diferentes alimentos durante días con una expresión when. La sentencia when es similar a switch en otros lenguajes de programación, pero when se interrumpe automáticamente al final de cada rama. También se asegura de que tu código cubra todas las ramas si revisas una enumeración.

  1. En Hello.kt, agrega una función llamada fishFood() que tome un día como String y muestre la comida del pescado como String. Usa when() para que cada día reciba un alimento específico. Ejecuta el programa varias veces para ver diferentes resultados.
fun fishFood (day : String) : String {
    var food = ""
    when (day) {
        "Monday" -> food = "flakes"
        "Tuesday" -> food = "pellets"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Saturday" -> food = "lettuce"
        "Sunday" -> food = "plankton"
    }
    return food
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)

    println ("Today is $day and the fish eat $food")
}
⇒ Today is Thursday and the fish eat granules
  1. Agrega una rama predeterminada a la expresión when con else. Para realizar pruebas, y para asegurarte de que a veces se toma el valor predeterminado en tu programa, quita las ramas Tuesday y Saturday.

    Tener una rama predeterminada garantiza que food obtenga un valor antes de que se muestre, de modo que ya no necesita inicializarse. Como el código ahora asigna una string a food solo una vez, puedes declarar food con val en lugar de var.
fun fishFood (day : String) : String {
    val food : String
    when (day) {
        "Monday" -> food = "flakes"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Sunday" -> food = "plankton"
        else -> food = "nothing"
    }
    return food
}
  1. Debido a que cada expresión tiene un valor, puedes hacer que este código sea un poco más conciso. Muestra el valor de la expresión when directamente y elimina la variable food. El valor de la expresión when es el valor de la última expresión de la rama que cumplió la condición.
fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

La versión final de tu programa es similar al siguiente código:

import java.util.*    // required import

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
        "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}

fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}

En esta tarea, aprenderá sobre los valores predeterminados para funciones y métodos. También aprenderás sobre las funciones compactas, que pueden hacer que tu código sea más conciso y legible, y pueden reducir la cantidad de rutas de código para las pruebas. Las funciones compactas también se denominan funciones de expresión única.

Paso 1: Crea un valor predeterminado para un parámetro

En Kotlin, puedes pasar argumentos por nombre de parámetro. También puedes especificar valores predeterminados para los parámetros: si un llamador no proporciona un argumento, se usa el valor predeterminado. Más adelante, cuando escribas métodos (funciones de miembro), significa que puedes evitar escribir muchas versiones sobrecargadas del mismo método.

  1. En Hello.kt, escribe una función swim() con un parámetro String llamado speed que imprima la velocidad de los peces. El parámetro speed tiene un valor predeterminado de "fast".
fun swim(speed: String = "fast") {
   println("swimming $speed")
}
  1. Desde la función main(), llama a la función swim() de tres maneras. Primero, llama a la función con el valor predeterminado. Luego, llama a la función y pasa el parámetro speed sin nombre. Luego, llama a la función nombrando el parámetro speed.
swim()   // uses default speed
swim("slow")   // positional argument
swim(speed="turtle-like")   // named parameter
⇒ swimming fast
swimming slow
swimming turtle-like

Paso 2: Agregue los parámetros obligatorios

Si no se especifica un valor predeterminado para un parámetro, siempre se debe pasar el argumento correspondiente.

  1. En Hello.kt, escribe una función shouldChangeWater() que tome tres parámetros: day, temperature y un nivel dirty. La función muestra true si se debe cambiar el agua, lo que sucede si es domingo, si la temperatura es demasiado alta o si el agua está muy sucio. El día de la semana es obligatorio, pero la temperatura predeterminada es 22 y el nivel no deseado predeterminado es 20.

    Usa una expresión when sin un argumento que, en Kotlin, actúe como una serie de comprobaciones if/else if.
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        temperature > 30 -> true
        dirty > 30 -> true
        day == "Sunday" ->  true
        else -> false
    }
}
  1. Llama a shouldChangeWater() desde feedTheFish() y proporciona el día correcto. El parámetro day no tiene un valor predeterminado, por lo que debes especificar un argumento. Los otros dos parámetros de shouldChangeWater() tienen valores predeterminados, por lo que no tienes que pasar argumentos por ellos.
fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
    println("Change water: ${shouldChangeWater(day)}")
}
=> Today is Thursday and the fish eat granules
Change water: false

Paso 3: Crea funciones compactas

La expresión when que escribiste en el paso anterior empaqueta mucha lógica en una pequeña cantidad de código. Si quisiera desembalar un poco o si las condiciones para comprobar fueran más complicadas, podría usar algunas variables locales que tienen el nombre correcto. Sin embargo, la forma de hacerlo es con funciones compactas.

Las funciones compactas, o funciones de una sola expresión, son un patrón común en Kotlin. Cuando una función muestra los resultados de una sola expresión, puedes especificar el cuerpo de la función después de un símbolo =, omitir las llaves {} y omitir return.

  1. en Hello.kt, agrega funciones compactas para probar las condiciones.
fun isTooHot(temperature: Int) = temperature > 30

fun isDirty(dirty: Int) = dirty > 30

fun isSunday(day: String) = day == "Sunday"
  1. Cambia shouldChangeWater() para llamar a las funciones nuevas.
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        isTooHot(temperature) -> true
        isDirty(dirty) -> true
        isSunday(day) -> true
        else  -> false
    }
}
  1. Ejecuta el programa. El resultado de println() con shouldChangeWater() debe ser el mismo que antes de comenzar a usar funciones compactas.

Valores predeterminados

El valor predeterminado de un parámetro no tiene que ser un valor. Puede ser otra función, como se muestra en el siguiente ejemplo parcial:

fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = getDirtySensorReading()): Boolean {
    ...

En esta tarea, aprenderás un poco sobre los filtros de Kotlin. Los filtros son una forma útil de formar parte de una lista según alguna condición.

Paso 1: Cree un filtro

  1. En Hello.kt, define una lista de decoraciones para acuarios en el nivel superior con listOf(). Puede reemplazar el contenido de Hello.kt.
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
  1. Crea una función main() nueva con una línea para imprimir solo las decoraciones que comiencen con la letra &'p'. El código de la condición del filtro se encuentra entre llaves {}, y it hace referencia a cada elemento a medida que se repite el filtro. Si la expresión muestra true, se incluye el elemento.
fun main() {
    println( decorations.filter {it[0] == 'p'})
}
  1. Ejecuta el programa. Verás el siguiente resultado en la ventana Run:
⇒ [pagoda, plastic plant]

Paso 2: Compara los filtros de filtro diferido

Si conoces los filtros de otros lenguajes, quizás te preguntes si los filtros de Kotlin son eager o diferidos. ¿La lista de resultados se crea de inmediato o cuando se accede a ella? En Kotlin, ocurre de la manera que la necesites. De forma predeterminada, filter está listo y, cada vez que usas el filtro, se crea una lista.

Para que el filtro sea diferido, puedes usar una Sequence, que es una colección que solo puede ver un elemento a la vez, desde el principio hasta el final. De manera conveniente, esta es exactamente la API que necesita un filtro diferido.

  1. En Hello.kt, cambia tu código para asignar la lista filtrada a una variable llamada eager y, luego, imprímela.
fun main() {
    val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

    // eager, creates a new list
    val eager = decorations.filter { it [0] == 'p' }
    println("eager: " + eager)
  1. Debajo del código, evalúa el filtro mediante Sequence con asSequence(). Asigna la secuencia a una variable llamada filtered y, luego, imprímela.
   // lazy, will wait until asked to evaluate
    val filtered = decorations.asSequence().filter { it[0] == 'p' }
    println("filtered: " + filtered)

Si muestras los resultados del filtro como Sequence, la variable filtered no mantendrá una lista nueva (contendrá un Sequence de los elementos de la lista y el conocimiento del filtro para aplicar a esos elementos). Cada vez que accedes a los elementos de Sequence, se aplica el filtro y se muestra el resultado.

  1. Para forzar la evaluación de la secuencia, conviértela en un List con toList(). Imprime el resultado.
    // force evaluation of the lazy list
    val newList = filtered.toList()
    println("new list: " + newList)
  1. Ejecuta el programa y observa el resultado.
⇒ eager: [pagoda, plastic plant]
filtered: kotlin.sequences.FilteringSequence@386cc1c4
new list: [pagoda, plastic plant]

Para visualizar lo que sucede con el Sequence y la evaluación diferida, usa la función map(). La función map() realiza una transformación simple en cada elemento de la secuencia.

  1. Con la misma lista decorations que en el ejemplo anterior, realiza una transformación con map() que no hace nada y simplemente muestra el elemento que se pasó. Agrega un elemento println() para mostrar cada vez que se accede a un elemento y asigna la secuencia a una variable llamada lazyMap.
    val lazyMap = decorations.asSequence().map {
        println("access: $it")
        it
    }
  1. Imprime lazyMap, imprime el primer elemento de lazyMap con first() y, luego, imprime lazyMap convertido en List.
    println("lazy: $lazyMap")
    println("-----")
    println("first: ${lazyMap.first()}")
    println("-----")
    println("all: ${lazyMap.toList()}")
  1. Ejecuta el programa y observa el resultado. Imprimir lazyMap simplemente imprime una referencia al Sequence: no se llama al println() interno. Al imprimir el primer elemento, solo se accede al primer elemento. La conversión de Sequence a List permite acceder a todos los elementos.
⇒ lazy: kotlin.sequences.TransformingSequence@5ba23b66
-----
access: rock
first: rock
-----
access: rock
access: pagoda
access: plastic plant
access: alligator
access: flowerpot
all: [rock, pagoda, plastic plant, alligator, flowerpot]
  1. Crea un Sequence nuevo con el filtro original antes de aplicar map. Imprime ese resultado.
    val lazyMap2 = decorations.asSequence().filter {it[0] == 'p'}.map {
        println("access: $it")
        it
    }
    println("-----")
    println("filtered: ${ lazyMap2.toList() }")
  1. Ejecuta el programa y observa los resultados adicionales. Al igual que cuando se obtiene el primer elemento, solo se llama al elemento println() interno para los elementos a los que se accede.
⇒
-----
access: pagoda
access: plastic plant
filtered: [pagoda, plastic plant]

En esta tarea, obtendrás una introducción a lambdas y funciones de orden superior en Kotlin.

Lambdas

Además de las funciones con nombres tradicionales, Kotlin admite lambdas. Una lambda es una expresión que realiza una función. Sin embargo, en lugar de declarar una función con nombre, debes declarar una función que no tiene nombre. Parte de lo que hace que esto sea útil es que la expresión lambda ahora se puede pasar como datos. En otros lenguajes, las lambdas se denominan funciones anónimas, literales de función o nombres similares.

Funciones de orden superior

Puedes crear una función de orden superior pasando una lambda a otra función. En la tarea anterior, creaste una función de orden superior llamada filter. Pasaste la siguiente expresión lambda a filter como la condición para verificar:
{it[0] == 'p'}

De manera similar, map es una función de orden superior, y la lambda que le pasaste fue la transformación que se debe aplicar.

Paso 1: Más información sobre lambdas

  1. Al igual que las funciones con nombre, las lambdas pueden tener parámetros. Para lambdas, los parámetros (y sus tipos, si es necesario) van a la izquierda de lo que se llama una flecha de función ->. El código para ejecutar se encuentra a la derecha de la flecha de función. Una vez que se asigna la lambda a una variable, puedes llamarla como una función.

    Usa el REPL (Herramientas > Kotlin > Kotlin REPL) y prueba el siguiente código:
var dirtyLevel = 20
val waterFilter = { dirty : Int -> dirty / 2}
println(waterFilter(dirtyLevel))
⇒ 10

En este ejemplo, la lambda toma un objeto Int llamado dirty y muestra dirty / 2. (porque quita la suciedad).

  1. La sintaxis de Kotlin para los tipos de funciones está estrechamente relacionada con su sintaxis para lambdas. Usa esta sintaxis para declarar de forma clara una variable que contenga una función:
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }

El código dice lo siguiente:

  • Crea una variable llamada waterFilter.
  • waterFilter puede ser cualquier función que tome un Int y muestre un Int.
  • Asigna una lambda a waterFilter.
  • La lambda muestra el valor del argumento dirty dividido por 2.

Ten en cuenta que ya no es necesario especificar el tipo del argumento lambda. El tipo se calcula por inferencia de tipo.

Paso 2: Crea una función de orden superior

Hasta ahora, los ejemplos de lambdas se ven principalmente como funciones. El verdadero poder de lambdas es usarlas para crear funciones de orden superior, en las que el argumento de una función es otra.

  1. Escribe una función de orden superior. A continuación, se muestra un ejemplo básico de una función que toma dos argumentos. El primer argumento es un número entero. El segundo argumento es una función que toma un número entero y muestra un número entero. Pruébalo en el REPL.
fun updateDirty(dirty: Int, operation: (Int) -> Int): Int {
   return operation(dirty)
}

El cuerpo del código llama a la función que se pasó como el segundo argumento y le pasa el primer argumento.

  1. Para llamar a esta función, pásale un número entero y una función.
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }
println(updateDirty(30, waterFilter))
⇒ 15

La función que pasas no tiene que ser lambda; en su lugar, puede ser una función con nombre normal. Para especificar el argumento como una función normal, usa el operador ::. De esta manera, Kotlin sabrá que estás pasando la referencia a la función como un argumento, sin intentar llamarla.

  1. Intenta pasar una función con nombre normal a updateDirty().
fun increaseDirty( start: Int ) = start + 1

println(updateDirty(15, ::increaseDirty))
⇒ 16
var dirtyLevel = 19;
dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}
println(dirtyLevel)
⇒ 42
  • Para crear un archivo de origen de Kotlin en IntelliJ IDEA, comienza con un proyecto de Kotlin.
  • Para compilar y ejecutar un programa en IntelliJ IDEA, haz clic en el triángulo verde junto a la función main(). El resultado aparece en una ventana de registro a continuación.
  • En IntelliJ IDEA, especifica argumentos de línea de comandos para pasar a la función main() en Run > Edit Configurations.
  • Casi todo en Kotlin tiene un valor. Puedes usar este hecho para que tu código sea más conciso mediante el uso de un valor de if o when como expresión o valor de retorno.
  • Los argumentos predeterminados eliminan la necesidad de múltiples versiones de una función o un método. Por ejemplo:
    fun swim(speed: String = "fast") { ... }
  • Las funciones compactas o de expresión única pueden hacer que tu código sea más legible. Por ejemplo:
    fun isTooHot(temperature: Int) = temperature > 30
  • Aprendiste algunos conceptos básicos sobre los filtros, que usan expresiones lambda. Por ejemplo:
    val beginsWithP = decorations.filter { it [0] == 'p' }
  • Una expresión lambda es una expresión que crea una función sin nombre. Las expresiones lambda se definen entre llaves {}.
  • En una función de orden superior, se pasa una función como una expresión lambda a otra función como datos. Por ejemplo:
    dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}

Esta lección incluye mucho, en especial si recién conoces las lambdas. En una lección posterior, se revisan las lambdas y las funciones de orden superior.

Documentación de Kotlin

Si necesitas más información sobre algún tema de este curso o si no puedes avanzar, https://kotlinlang.org es tu mejor punto de partida.

Instructivos de Kotlin

El sitio web https://try.kotlinlang.org incluye instructivos enriquecidos llamados Kotlin Koans, un intérprete basado en la Web, y un conjunto completo de documentación de referencia con ejemplos.

Curso de Udacity

Para ver el curso de Udacity sobre este tema, consulta el Capacitación de Kotlin para programadores.

IntelliJ IDEA

Puedes encontrar la documentación de IntelliJ IDEA en el sitio web de JetBrains.

En esta sección, se enumeran las posibles tareas para los alumnos que trabajan con este codelab como parte de un curso que dicta un instructor. Depende del instructor hacer lo siguiente:

  • Si es necesario, asigna la tarea.
  • Informa a los alumnos cómo enviar los deberes.
  • Califica las tareas.

Los instructores pueden usar estas sugerencias lo poco o lo que quieran, y deben asignar cualquier otra tarea que consideren apropiada.

Si estás trabajando en este codelab por tu cuenta, usa estas tareas para poner a prueba tus conocimientos.

Responde estas preguntas

Pregunta 1

La función contains(element: String) muestra true si la string element está incluida en la string a la que se llama. ¿Cuál será el resultado del siguiente código?

val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

println(decorations.filter {it.contains('p')})

[pagoda, plastic, plant]

[pagoda, plastic plant]

[pagoda, plastic plant, flowerpot]

[rock, alligator]

Pregunta 2

En la siguiente definición de función, ¿cuál de los parámetros es obligatorio?
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20, numDecorations: Int = 0): Boolean {...}

numDecorations

dirty

day

temperature

Pregunta 3

Puedes pasar una función con nombre normal (no el resultado de llamarla) a otra función. ¿Cómo pasarías increaseDirty( start: Int ) = start + 1 a updateDirty(dirty: Int, operation: (Int) -> Int)?

updateDirty(15, &increaseDirty())

updateDirty(15, increaseDirty())

updateDirty(15, ("increaseDirty()"))

updateDirty(15, ::increaseDirty)

Continúa con la siguiente lección: 4. Clases y objetos

Para obtener una descripción general del curso, incluidos vínculos a otros codelabs, consulta "Capacitación de Kotlin para programadores: Bienvenido al curso."