Kotlin Bootcamp for Programmers 3: Functions

Questo codelab fa parte del corso Kotlin Bootcamp for Programmers. Per ottenere il massimo valore da questo corso, ti consigliamo di seguire le codelab in sequenza. A seconda delle tue conoscenze, potresti riuscire a leggere rapidamente alcune sezioni. Questo corso è rivolto ai programmatori che conoscono un linguaggio orientato agli oggetti e vogliono imparare Kotlin.

Introduzione

In questo codelab, creerai un programma Kotlin e imparerai a utilizzare le funzioni in Kotlin, inclusi i valori predefiniti per i parametri, i filtri, le espressioni lambda e le funzioni compatte.

Anziché creare una singola app di esempio, le lezioni di questo corso sono progettate per sviluppare le tue conoscenze, ma sono semi-indipendenti l'una dall'altra, in modo che tu possa scorrere rapidamente le sezioni che conosci. Per collegarli, molti esempi utilizzano un tema acquatico. Se vuoi scoprire tutta la storia dell'acquario, dai un'occhiata al corso Kotlin Bootcamp for Programmers di Udacity.

Cosa devi già sapere

  • Nozioni di base di un linguaggio di programmazione moderno, orientato agli oggetti e con tipizzazione statica
  • Come programmare con classi, metodi e gestione delle eccezioni in almeno una lingua
  • Come utilizzare il ciclo REPL (Read-Eval-Print Loop) di Kotlin in IntelliJ IDEA
  • Le basi di Kotlin, inclusi tipi, operatori e cicli

Questo codelab è rivolto ai programmatori che conoscono un linguaggio orientato agli oggetti e vogliono saperne di più su Kotlin.

Obiettivi didattici

  • Come creare un programma con una funzione main() e argomenti in IntelliJ IDEA
  • Come utilizzare i valori predefiniti e le funzioni compatte
  • Come applicare i filtri per gli elenchi
  • Come creare espressioni lambda di base e funzioni di ordine superiore

In questo lab proverai a:

  • Utilizza REPL per provare un po' di codice.
  • Utilizza IntelliJ IDEA per creare programmi Kotlin di base.

In questa attività, creerai un programma Kotlin e imparerai a usare la funzione main(), nonché a passare argomenti a un programma dalla riga di comando.

Potresti ricordare la funzione printHello() che hai inserito nel REPL in un precedente codelab:

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

printHello()
⇒ Hello World

Definisci le funzioni utilizzando la parola chiave fun, seguita dal nome della funzione. Come per altri linguaggi di programmazione, le parentesi () vengono utilizzate per gli argomenti della funzione, se presenti. Le parentesi graffe {} racchiudono il codice della funzione. Non esiste un tipo restituito per questa funzione, perché non restituisce nulla.

Passaggio 1: crea un file Kotlin

  1. Apri IntelliJ IDEA.
  2. Il riquadro Progetto a sinistra in IntelliJ IDEA mostra un elenco dei file e delle cartelle del progetto. Individua e fai clic con il tasto destro del mouse sulla cartella src in Hello Kotlin. (Dovresti già avere il progetto Hello Kotlin del codelab precedente.)
  3. Seleziona Nuovo > File / classe Kotlin.
  4. Mantieni Tipo come File e assegna al file il nome Hello.
  5. Fai clic su OK.

Ora nella cartella src è presente un file denominato Hello.kt.

Passaggio 2: aggiungi il codice ed esegui il programma

  1. Come per altri linguaggi, la funzione Kotlin main() specifica il punto di ingresso per l'esecuzione. Tutti gli argomenti della riga di comando vengono passati come array di stringhe.

    Digita o incolla il seguente codice nel file Hello.kt :
fun main(args: Array<String>) {
    println("Hello, world!")
}

Come la funzione printHello() precedente, questa funzione non ha un'istruzione return. Ogni funzione in Kotlin restituisce qualcosa, anche quando non viene specificato nulla in modo esplicito. Pertanto, una funzione come main() restituisce un tipo kotlin.Unit, che è il modo in cui Kotlin indica che non è presente alcun valore.

  1. Per eseguire il programma, fai clic sul triangolo verde a sinistra della funzione main(). Seleziona Run 'HelloKt' (Esegui "HelloKt") dal menu.
  2. IntelliJ IDEA compila il programma e lo esegue. I risultati vengono visualizzati in un riquadro del log in basso, come mostrato di seguito.

Passaggio 3: passa gli argomenti a main()

Poiché esegui il programma da IntelliJ IDEA e non dalla riga di comando, devi specificare gli argomenti del programma in modo leggermente diverso.

  1. Seleziona Esegui > Modifica configurazioni. Si apre la finestra Run/Debug Configurations (Configurazioni di esecuzione/debug).
  2. Digita Kotlin! nel campo Argomenti del programma.
  3. Fai clic su OK.

Passaggio 4: modifica il codice per utilizzare un modello di stringa

Un modello di stringa inserisce una variabile o un'espressione in una stringa e $ specifica che una parte della stringa sarà una variabile o un'espressione. Le parentesi graffe {} racchiudono l'espressione, se presente.

  1. In Hello.kt, modifica il messaggio di saluto in modo che utilizzi il primo argomento passato al programma, args[0], anziché "world".
fun main(args: Array<String>) {
    println("Hello, ${args[0]}")
}
  1. Esegui il programma e l'output include l'argomento che hai specificato.
⇒ Hello, Kotlin!

In questa attività, scoprirai perché quasi tutto in Kotlin ha un valore e perché è utile.

Alcune altre lingue hanno istruzioni, ovvero righe di codice senza un valore. In Kotlin, quasi tutto è un'espressione e ha un valore, anche se questo valore è kotlin.Unit.

  1. In Hello.kt, scrivi il codice in main() per assegnare un println() a una variabile denominata isUnit e stampala. (println() non restituisce un valore, quindi restituisce kotlin.Unit.)
// Will assign kotlin.Unit
val isUnit = println("This is an expression")
println(isUnit)
  1. Esegui il programma. Il primo println() stampa la stringa "This is an expression". Il secondo println() stampa il valore della prima istruzione println(), ovvero kotlin.Unit.
⇒ This is an expression
kotlin.Unit
  1. Dichiara una val denominata temperature e inizializzala a 10.
  2. Dichiara un altro val chiamato isHot e assegna il valore restituito di un'istruzione if/else a isHot, come mostrato nel seguente codice. Poiché si tratta di un'espressione, puoi utilizzare immediatamente il valore dell'espressione if.
val temperature = 10
val isHot = if (temperature > 50) true else false
println(isHot)
⇒ false
  1. Utilizza il valore di un'espressione in un modello di stringa. Aggiungi del codice per controllare la temperatura e determinare se un pesce è sicuro o troppo caldo, quindi esegui il programma.
val temperature = 10
val message = "The water temperature is ${ if (temperature > 50) "too warm" else "OK" }."
println(message)
⇒ The water temperature is OK.

In questa attività, scoprirai di più sulle funzioni in Kotlin e sull'espressione condizionale when, molto utile.

Passaggio 1: crea alcune funzioni

In questo passaggio, metti insieme alcune delle cose che hai imparato e crea funzioni con tipi diversi. Puoi sostituire i contenuti di Hello.kt con questo nuovo codice.

  1. Scrivi una funzione chiamata feedTheFish() che chiama randomDay() per ottenere un giorno casuale della settimana. Utilizza un modello di stringa per stampare un food che il pesce possa mangiare quel giorno. Per ora, i pesci mangiano lo stesso cibo ogni giorno.
fun feedTheFish() {
    val day = randomDay()
    val food = "pellets"
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}
  1. Scrivi la funzione randomDay() per scegliere un giorno a caso da un array e restituirlo.

La funzione nextInt() accetta un limite intero, che limita il numero da Random() a 0 fino a 6 per corrispondere all'array week.

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
            "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}
  1. Le funzioni Random() e nextInt() sono definite in java.util.*. All'inizio del file, aggiungi l'importazione necessaria:
import java.util.*    // required import
  1. Esegui il programma e controlla l'output.
⇒ Today is Tuesday and the fish eat pellets

Passaggio 2: utilizza un'espressione when

Estendendo ulteriormente questo concetto, modifica il codice in modo da scegliere cibi diversi per giorni diversi utilizzando un'espressione when. L'istruzione when è simile a switch in altri linguaggi di programmazione, ma when si interrompe automaticamente alla fine di ogni ramo. Inoltre, assicura che il codice copra tutti i rami se stai controllando un'enumerazione.

  1. In Hello.kt, aggiungi una funzione chiamata fishFood() che accetta un giorno come String e restituisce il cibo del pesce per il giorno come String. Utilizza when(), in modo che ogni giorno il pesce riceva un alimento specifico. Esegui il programma più volte per visualizzare output diversi.
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. Aggiungi un ramo predefinito all'espressione when utilizzando else. Per i test, per assicurarti che il valore predefinito venga utilizzato a volte nel tuo programma, rimuovi i rami Tuesday e Saturday.

    La presenza di un ramo predefinito garantisce che food riceva un valore prima di essere restituito, quindi non è più necessario inizializzarlo. Poiché ora il codice assegna una stringa a food una sola volta, puoi dichiarare food con val anziché 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. Poiché ogni espressione ha un valore, puoi rendere questo codice un po' più conciso. Restituisci direttamente il valore dell'espressione when ed elimina la variabile food. Il valore dell'espressione when è il valore dell'ultima espressione del ramo che ha soddisfatto la condizione.
fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

La versione finale del programma è simile al codice riportato di seguito.

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()
}

In questa attività, scoprirai i valori predefiniti per funzioni e metodi. Scopri anche le funzioni compatte, che possono rendere il codice più conciso e leggibile e ridurre il numero di percorsi del codice per i test. Le funzioni compatte sono chiamate anche funzioni a espressione singola.

Passaggio 1: crea un valore predefinito per un parametro

In Kotlin, puoi passare argomenti in base al nome del parametro. Puoi anche specificare i valori predefiniti per i parametri: se un argomento non viene fornito dal chiamante, viene utilizzato il valore predefinito. In seguito, quando scrivi metodi (funzioni membro), puoi evitare di scrivere molte versioni di overload dello stesso metodo.

  1. In Hello.kt, scrivi una funzione swim() con un parametro String denominato speed che stampa la velocità del pesce. Il parametro speed ha un valore predefinito di "fast".
fun swim(speed: String = "fast") {
   println("swimming $speed")
}
  1. Dalla funzione main(), chiama la funzione swim() in tre modi. Chiama prima la funzione utilizzando il valore predefinito. Quindi chiama la funzione e passa il parametro speed senza un nome, poi chiama la funzione assegnando un nome al parametro speed.
swim()   // uses default speed
swim("slow")   // positional argument
swim(speed="turtle-like")   // named parameter
⇒ swimming fast
swimming slow
swimming turtle-like

Passaggio 2: aggiungi i parametri obbligatori

Se per un parametro non viene specificato alcun valore predefinito, l'argomento corrispondente deve essere sempre passato.

  1. In Hello.kt, scrivi una funzione shouldChangeWater() che accetta tre parametri: day, temperature e un livello dirty. La funzione restituisce true se l'acqua deve essere cambiata, il che accade se è domenica, se la temperatura è troppo alta o se l'acqua è troppo sporca. Il giorno della settimana è obbligatorio, ma la temperatura predefinita è 22 e il livello di sporco predefinito è 20.

    Utilizza un'espressione when senza argomenti, che in Kotlin funge da serie di controlli 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. Chiama shouldChangeWater() da feedTheFish() e indica il giorno. Il parametro day non ha un valore predefinito, quindi devi specificare un argomento. Gli altri due parametri di shouldChangeWater() hanno valori predefiniti, quindi non devi passare argomenti per questi parametri.
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

Passaggio 3: crea funzioni compatte

L'espressione when che hai scritto nel passaggio precedente racchiude molta logica in una piccola quantità di codice. Se volessi analizzarlo un po' più nel dettaglio o se le condizioni da verificare fossero più complicate, potresti utilizzare alcune variabili locali con nomi descrittivi. Il modo di farlo in Kotlin è con le funzioni compatte.

Le funzioni compatte, o funzioni a espressione singola, sono un pattern comune in Kotlin. Quando una funzione restituisce i risultati di una singola espressione, puoi specificare il corpo della funzione dopo il simbolo =, omettere le parentesi graffe {} e omettere return.

  1. In Hello.kt, aggiungi funzioni compatte per testare le condizioni.
fun isTooHot(temperature: Int) = temperature > 30

fun isDirty(dirty: Int) = dirty > 30

fun isSunday(day: String) = day == "Sunday"
  1. Modifica shouldChangeWater() per chiamare le nuove funzioni.
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. Esegui il programma. L'output di println() con shouldChangeWater() dovrebbe essere lo stesso di prima del passaggio all'utilizzo delle funzioni compatte.

Valori predefiniti

Il valore predefinito di un parametro non deve essere un valore. Può essere un'altra funzione, come mostrato nel seguente esempio parziale:

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

In questa attività, imparerai qualcosa sui filtri in Kotlin. I filtri sono un modo pratico per ottenere una parte di un elenco in base a una condizione.

Passaggio 1: crea un filtro

  1. In Hello.kt, definisci un elenco di decorazioni per l'acquario al livello superiore con listOf(). Puoi sostituire i contenuti di Hello.kt.
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
  1. Crea una nuova funzione main() con una riga per stampare solo le decorazioni che iniziano con la lettera "p". Il codice per la condizione di filtro è tra parentesi graffe {} e it si riferisce a ogni elemento mentre il filtro scorre. Se l'espressione restituisce true, l'elemento viene incluso.
fun main() {
    println( decorations.filter {it[0] == 'p'})
}
  1. Esegui il programma e vedrai il seguente output nella finestra Esegui:
⇒ [pagoda, plastic plant]

Passaggio 2: confronta i filtri eager e lazy

Se hai familiarità con i filtri in altre lingue, potresti chiederti se i filtri in Kotlin sono eager o lazy. L'elenco dei risultati viene creato immediatamente o quando si accede all'elenco? In Kotlin, avviene nel modo che preferisci. Per impostazione predefinita, filter è eager e ogni volta che utilizzi il filtro viene creato un elenco.

Per rendere il filtro pigro, puoi utilizzare un Sequence, ovvero una raccolta che può esaminare un solo elemento alla volta, iniziando dall'inizio e andando fino alla fine. Fortunatamente, questa è esattamente l'API di cui ha bisogno un filtro pigro.

  1. In Hello.kt, modifica il codice per assegnare l'elenco filtrato a una variabile denominata eager, quindi stampalo.
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. Sotto questo codice, valuta il filtro utilizzando un Sequence con asSequence(). Assegna la sequenza a una variabile chiamata filtered e stampala.
   // lazy, will wait until asked to evaluate
    val filtered = decorations.asSequence().filter { it[0] == 'p' }
    println("filtered: " + filtered)

Quando restituisci i risultati del filtro come Sequence, la variabile filtered non conterrà un nuovo elenco, ma un Sequence degli elementi dell'elenco e la conoscenza del filtro da applicare a questi elementi. Ogni volta che accedi agli elementi di Sequence, il filtro viene applicato e il risultato ti viene restituito.

  1. Forza la valutazione della sequenza convertendola in un List con toList(). Stampa il risultato.
    // force evaluation of the lazy list
    val newList = filtered.toList()
    println("new list: " + newList)
  1. Esegui il programma e osserva l'output.
⇒ eager: [pagoda, plastic plant]
filtered: kotlin.sequences.FilteringSequence@386cc1c4
new list: [pagoda, plastic plant]

Per visualizzare cosa succede con Sequence e la valutazione pigra, utilizza la funzione map(). La funzione map() esegue una semplice trasformazione su ogni elemento della sequenza.

  1. Con lo stesso elenco decorations di prima, esegui una trasformazione con map() che non fa nulla e restituisce semplicemente l'elemento passato. Aggiungi un println() per mostrare ogni volta che viene eseguito l'accesso a un elemento e assegna la sequenza a una variabile denominata lazyMap.
    val lazyMap = decorations.asSequence().map {
        println("access: $it")
        it
    }
  1. Stampa lazyMap, stampa il primo elemento di lazyMap utilizzando first() e stampa lazyMap convertito in List.
    println("lazy: $lazyMap")
    println("-----")
    println("first: ${lazyMap.first()}")
    println("-----")
    println("all: ${lazyMap.toList()}")
  1. Esegui il programma e osserva l'output. La stampa di lazyMap stampa solo un riferimento a Sequence. println() interno non viene chiamato. La stampa del primo elemento consente di accedere solo al primo elemento. La conversione di Sequence in List consente di accedere a tutti gli elementi.
⇒ 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 nuovo Sequence utilizzando il filtro originale prima di applicare map. Stampa il risultato.
    val lazyMap2 = decorations.asSequence().filter {it[0] == 'p'}.map {
        println("access: $it")
        it
    }
    println("-----")
    println("filtered: ${ lazyMap2.toList() }")
  1. Esegui il programma e osserva l'output aggiuntivo. Come per l'ottenimento del primo elemento, l'println() interno viene chiamato solo per gli elementi a cui si accede.
⇒
-----
access: pagoda
access: plastic plant
filtered: [pagoda, plastic plant]

In questa attività, riceverai un'introduzione alle espressioni lambda e alle funzioni di ordine superiore in Kotlin.

Lambda

Oltre alle tradizionali funzioni con nome, Kotlin supporta le espressioni lambda. Una lambda è un'espressione che crea una funzione. Invece di dichiarare una funzione con nome, dichiari una funzione senza nome. Parte di ciò che rende utile questa funzionalità è che l'espressione lambda ora può essere passata come dati. In altre lingue, le funzioni lambda sono chiamate funzioni anonime, valori letterali di funzione o nomi simili.

Funzioni di ordine superiore

Puoi creare una funzione di ordine superiore passando una funzione lambda a un'altra funzione. Nell'attività precedente, hai creato una funzione di ordine superiore denominata filter. Hai passato la seguente espressione lambda a filter come condizione da controllare:
{it[0] == 'p'}

Allo stesso modo, map è una funzione di ordine superiore e la funzione lambda che hai passato era la trasformazione da applicare.

Passaggio 1: scopri di più sulle espressioni lambda

  1. Come le funzioni con nome, le funzioni lambda possono avere parametri. Per le espressioni lambda, i parametri (e i relativi tipi, se necessario) si trovano a sinistra di quella che viene chiamata freccia di funzione ->. Il codice da eseguire si trova a destra della freccia della funzione. Una volta assegnata a una variabile, puoi chiamare la lambda come una funzione.

    Utilizzando REPL (Strumenti > Kotlin > Kotlin REPL), prova questo codice:
var dirtyLevel = 20
val waterFilter = { dirty : Int -> dirty / 2}
println(waterFilter(dirtyLevel))
⇒ 10

In questo esempio, la lambda accetta un Int denominato dirty e restituisce dirty / 2. (Perché il filtraggio rimuove lo sporco.)

  1. La sintassi di Kotlin per i tipi di funzioni è strettamente correlata alla sintassi per le espressioni lambda. Utilizza questa sintassi per dichiarare in modo pulito una variabile che contiene una funzione:
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }

Ecco cosa dice il codice:

  • Crea una variabile denominata waterFilter.
  • waterFilter può essere qualsiasi funzione che accetta un Int e restituisce un Int.
  • Assegna una lambda a waterFilter.
  • La funzione lambda restituisce il valore dell'argomento dirty diviso per 2.

Tieni presente che non devi più specificare il tipo di argomento lambda. Il tipo viene calcolato tramite l'inferenza del tipo.

Passaggio 2: crea una funzione di ordine superiore

Finora, gli esempi di lambda sembrano per lo più funzioni. Il vero punto di forza delle funzioni lambda è la possibilità di utilizzarle per creare funzioni di ordine superiore, in cui l'argomento di una funzione è un'altra funzione.

  1. Scrivi una funzione di ordine superiore. Ecco un esempio di base, una funzione che accetta due argomenti. Il primo argomento è un numero intero. Il secondo argomento è una funzione che accetta un numero intero e ne restituisce un altro. Provalo nel REPL.
fun updateDirty(dirty: Int, operation: (Int) -> Int): Int {
   return operation(dirty)
}

Il corpo del codice chiama la funzione passata come secondo argomento e le trasmette il primo argomento.

  1. Per chiamare questa funzione, trasmetti un numero intero e una funzione.
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }
println(updateDirty(30, waterFilter))
⇒ 15

La funzione che trasmetti non deve essere una funzione lambda, ma può essere una normale funzione con nome. Per specificare l'argomento come funzione regolare, utilizza l'operatore ::. In questo modo Kotlin sa che stai passando il riferimento alla funzione come argomento, non che stai cercando di chiamarla.

  1. Prova a passare una normale funzione con nome 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
  • Per creare un file di origine Kotlin in IntelliJ IDEA, inizia con un progetto Kotlin.
  • Per compilare ed eseguire un programma in IntelliJ IDEA, fai clic sul triangolo verde accanto alla funzione main(). L'output viene visualizzato in una finestra di log qui sotto.
  • In IntelliJ IDEA, specifica gli argomenti della riga di comando da passare alla funzione main() in Esegui > Modifica configurazioni.
  • Quasi tutto in Kotlin ha un valore. Puoi utilizzare questo fatto per rendere il codice più conciso utilizzando il valore di un if o when come espressione o valore restituito.
  • Gli argomenti predefiniti eliminano la necessità di più versioni di una funzione o di un metodo. Ad esempio:
    fun swim(speed: String = "fast") { ... }
  • Le funzioni compatte, o a singola espressione, possono rendere il codice più leggibile. Ad esempio:
    fun isTooHot(temperature: Int) = temperature > 30
  • Hai imparato alcune nozioni di base sui filtri, che utilizzano le espressioni lambda. Ad esempio:
    val beginsWithP = decorations.filter { it [0] == 'p' }
  • Un'espressione lambda è un'espressione che crea una funzione senza nome. Le espressioni lambda sono definite tra parentesi graffe {}.
  • In una funzione di ordine superiore, passi una funzione, ad esempio un'espressione lambda, a un'altra funzione come dati. Ad esempio:
    dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}

Questa lezione è ricca di contenuti, soprattutto se non hai mai utilizzato le espressioni lambda. Una lezione successiva riprende le espressioni lambda e le funzioni di ordine superiore.

Documentazione di Kotlin

Se vuoi maggiori informazioni su un argomento di questo corso o se hai difficoltà, https://kotlinlang.org è il punto di partenza migliore.

Tutorial di Kotlin

Il sito web https://try.kotlinlang.org include tutorial dettagliati chiamati Kotlin Koans, un interprete basato sul web e una serie completa di documentazione di riferimento con esempi.

Corso Udacity

Per visualizzare il corso Udacity su questo argomento, consulta Kotlin Bootcamp for Programmers.

IntelliJ IDEA

La documentazione di IntelliJ IDEA è disponibile sul sito web di JetBrains.

Questa sezione elenca i possibili compiti a casa per gli studenti che seguono questo codelab nell'ambito di un corso guidato da un insegnante. Spetta all'insegnante:

  • Assegna i compiti, se richiesto.
  • Comunica agli studenti come inviare i compiti.
  • Valuta i compiti a casa.

Gli insegnanti possono utilizzare questi suggerimenti nella misura che ritengono opportuna e sono liberi di assegnare qualsiasi altro compito a casa che ritengono appropriato.

Se stai seguendo questo codelab in autonomia, sentiti libero di utilizzare questi compiti per casa per mettere alla prova le tue conoscenze.

Rispondi a queste domande

Domanda 1

La funzione contains(element: String) restituisce true se la stringa element è contenuta nella stringa su cui viene chiamata. Quale sarà l'output del seguente codice?

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]

Domanda 2

Nella seguente definizione di funzione, quale dei parametri è obbligatorio?
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20, numDecorations: Int = 0): Boolean {...}

numDecorations

dirty

day

temperature

Domanda 3

Puoi passare una normale funzione con nome (non il risultato della sua chiamata) a un'altra funzione. Come faresti passare increaseDirty( start: Int ) = start + 1 a updateDirty(dirty: Int, operation: (Int) -> Int)?

updateDirty(15, &increaseDirty())

updateDirty(15, increaseDirty())

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

updateDirty(15, ::increaseDirty)

Passa alla lezione successiva: 4. Classi e oggetti

Per una panoramica del corso, inclusi i link ad altri codelab, vedi "Kotlin Bootcamp for Programmers: Welcome to the course" (Kotlin Bootcamp per programmatori: benvenuto al corso).