# Tutorial per Kotlin: i primi passi con il nuovo linguaggio di programmazione

La versione 1.0 di Kotlin è disponibile solo dal 2016, ma è già molto apprezzata perché rappresenta una valida alternativa a Java. Questo linguaggio di programmazione basato su oggetti è stato sviluppato da JetBrains, una società ceca di sviluppo software. Convince molte persone per il suo **carattere snello** e per il numero ridotto di errori di runtime che produce, in particolare le temute *NullPointerExceptions*. Kotlin è particolarmente apprezzato nello sviluppo di applicazioni Android, ma anche come punto di partenza per le applicazioni JavaScript, dove il giovane linguaggio di programmazione gode di enorme popolarità.

Kotlin è **fondamentalmente basato su Java**: sebbene i due linguaggi di programmazione non siano compatibili, Kotlin viene convertito in bytecode, che può essere letto da una Java Virtual Machine (JVM).

## Istruzioni per usare Kotlin con esempi

Per iniziare con Kotlin potete scaricare il [compilatore dal sito ufficiale](https://kotlinlang.org/docs/tutorials/command-line.html "Tutorial per installare il compiler di Kotlin"). La cosa migliore è utilizzare un ambiente di sviluppo (IDE), come ad esempio IntelliJ IDEA (sempre di JetBrains), Eclipse (con relativo plug-in), NetBeans e Android Studio, che supportano Kotlin.

---

### Consiglio

I produttori di Kotlin [mettono a disposizione una sandbox online](https://play.kotlinlang.org/ "Kotlin Playground") dove potete provare tutti gli esempi.

---

### Pacchetti (packages)

All'inizio di un progetto dovete importare i pacchetti necessari per la sua realizzazione e definire il pacchetto su cui state lavorando. I pacchetti **contengono classi e funzioni**.

```none
package test.bar
import foo.bar
import footoo.bar as footoo
```

Per evitare problemi con nomi identici è possibile rinominare i pacchetti in Kotlin con *as*. L'**assegnazione dei nomi** **ai pacchetti** non deve seguire la struttura di directory in cui si trovano, ma si raccomanda comunque questa prassi per motivi di chiarezza.

---

### N.B.

Kotlin carica automaticamente i pacchetti più importanti in ogni progetto.

---

A differenza di Java, Kotlin permette anche di **importare singole funzioni da altri pacchetti**. Per farlo dovete specificare il percorso corretto:

```none
import foo.bar.myFunction
```

La funzione può quindi essere utilizzata normalmente.

---

### Consiglio

Le righe di codice in Kotlin non richiedono più l'uso di terminatori, come un punto e virgola.

---

### Variabili

Kotlin prevede **due diversi tipi di variabili**: quelle che indicano un riferimento immutabile e non sono modificabili, introdotte con *val*, e quelle il cui valore può essere modificato nel corso del programma, che vengono introdotte con *var*.

```none
val name = "Clara Oswald"
var age = 22
```

A differenza del nome, che è costante, l'età può essere modificata, ad esempio in una funzione.

---

### N.B.

In questo esempio, Kotlin ha impostato autonomamente il valore della variabile. È anche possibile etichettare specificamente questi tipi di base.

---

### Tipi di base (basic types)

Kotlin lavora con specifici tipi di variabili e classi. In Kotlin ogni tipo consiste in un oggetto, il che lo rende leggermente diverso da Java. Mentre il linguaggio di programmazione più vecchio deve prima impacchettare i tipi primitivi in una classe [wrapper](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/cose-un-wrapper/ "Cos’è un wrapper?") per renderli oggetti, in Kotlin non è necessario perché tutti i tipi sono già oggetti.

#### Numeri (numbers)

In Kotlin è possibile inserire numeri senza un marcatore specifico: il compilatore capisce che si tratta di valori numerici. Le virgole sono indicate da punti. È possibile utilizzare anche numeri esadecimali. Per una migliore leggibilità è possibile visualizzare i separatori decimali mediante trattini bassi. Kotlin conosce **diversi tipi di numeri**, ognuno dei quali può avere una dimensione massima diversa:

- Long: 64 bit
- Int: 32 bit
- Short: 16 bit
- Byte: 8 bit
- Double: 64 bit
- Float: 32 bit

Double e Float sono **numeri a virgola mobile** che si comportano diversamente dai numeri a virgola fissa nei calcoli complessi. Come tutti i tipi, è possibile contrassegnare concretamente i numeri nel codice.

```none
val myNumber: Long = 40
```

È possibile convertire un numero di un tipo in un altro.

```none
val myInt = 600
val myLong= myInt.toLong()
```

Il comando *toLong* converte il valore Int in un valore Long. Il comando funziona allo stesso modo per gli altri tipi di numeri.

#### String

Quando parliamo di string intendiamo una parola o una frase intera, ovvero una stringa di caratteri. Per utilizzarli in Kotlin inserite il testo scritto **tra virgolette doppie**. Se volete inserire più righe di testo, sono necessarie tre virgolette doppie sia all'inizio che alla fine (Raw String).

```none
val myString = "Questo è uno string singolo."
val myLongString = """Questo è uno string
su più righe."""
```

Come in molti altri linguaggi di programmazione, anche Kotlin supporta le **sequenze** **di escape**: anteponendo un backslash davanti a un carattere indicate che questo non appartiene alla stringa vera e propria e che deve essere trattato come un carattere di controllo. Con l'aiuto del backslash potete inserire nella stringa anche caratteri che hanno un significato diverso in Kotlin. Queste sono le sequenze di escape possibili:

- \\t: tab
- \\b: backspace
- \\n: nuova riga
- \\r: carriage return (ritorno a capo)
- \\': virgoletta singola
- \\": virgoletta doppia
- \\\\: backslash
- \\$: simbolo del dollaro

Il simbolo del dollaro viene utilizzato nelle stringhe per inserire **metacaratteri**, i quali possono essere impostati come variabili in un passaggio precedente. Il metacarattere viene quindi sostituito nell'output da un valore effettivo.

```none
val author = "Sandra"
val myString = "Questo testo è di $autore"
```

#### Caratteri (characters)

In aggiunta agli string per i singoli caratteri Kotlin fornisce anche il tipo di dati speciale character. Questi vanno tuttavia inseriti tra **virgolette singole** piuttosto che tra quelle doppie.

```none
var model = &apos;A&apos;
```

#### Booleano

Il basic type boolean può assumere soltanto due valori, ***vero (true)* o *falso (false)***.

### Array

In Kotlin un array è una **raccolta di dati**. Un array è formato da *arrayOf()* o *Array()*. La prima funzione è semplice:

```none
val myArray1 = arrayOf(0, 1, 2, 3, 4, 5)
```

In questo modo viene creato un array con le cifre da 1 a 5. In queste raccolte possono essere incluse anche **altri tipi** di string e booleani, anche misti. Se si vuole limitare l'array a un solo tipo, lo si specifica nella funzione.

```none
val myArray2 = arrayOf<int>(10, 20, 30)</int>
val myArray3 = booleanArrayOf(true, true, false)
```

Il costruttore Kotlin *Array()* è più complesso: qui è necessario specificare anche la lunghezza e una funzione lambda.

```none
val myArray4 = Array(6, { i -> i })
```

Il costruttore crea un array a sei cifre partendo da zero: 0, 1, 2, 3, 4, 5.

---

### N.B.

L'argomento relativo a costruttori e lambda sarà approfondito più avanti.

---

Ogni inserimento in un array è indicizzato e può essere chiamato tramite questo **indice**. A tale scopo vengono utilizzate le parentesi quadre nelle quali viene specificata la posizione dell'inserimento nell'elenco.

```none
fun main() {
	val myArray5 = arrayOf("Jan", "Maria", "Samuel")
	println(myArray5[2])
}
```

---

### N.B.

Il risultato della funzione in questo caso sarà "Samuel", dato che il conteggio inizia da 0.

---

### Operatori

Come molti altri linguaggi di programmazione, anche Kotlin lavora con diversi operatori che potete integrare nel vostro codice sorgente. Questi includono **operatori matematici** (*+*, *-*, *\**, */*, *%*), **operatori di confronto** (*&lt;*, *&gt;*, *&lt;=*, *&gt;=*, *==*, *!=*) e **operatori logici** (*&amp;&amp;*, *||*, *!*). Strettamente legati agli operatori sono le **keyword**, ovvero termini che hanno un significato fisso in Kotlin che non può essere cambiato.

---

### Consiglio

Nella documentazione ufficiale di Kotlin potete trovare una [lista completa di tutte le keyword e degli operatori](https://kotlinlang.org/docs/reference/keyword-reference.html "Keyword e operatori di Kotlin").

---

### Range

In Kotlin un range descrive un tipo che va da un determinato punto a un altro. Per creare un range si utilizza l'operatore *..* o le funzioni *rangeTo()* o *downTo()*. La variante con i due punti è incrementale, mentre con le due funzioni si definisce una direzione.

```none
val range1 = 1..5
val range2 = 1.rangeTo(5)
val range3 = 5.downTo(1)
```

In queste versioni semplici sono sufficienti step con valore 1 per creare un range. Se invece volete modificare il **valore degli step** dovete utilizzare la relativa funzione *step*.

```none
val range4 = 0..10 step(2)
```

Per **indirizzare dati singoli nel range**, utilizzate l'operatore *in*. In questo modo potete per esempio creare espressioni o cicli. Per verificare se un valore non appartiene al range viene utilizzato l'operatore *!in*.

```none
val range5 = 0..10
fun main() {
	for (n in range5) {
		println(n)
	}
	if (7 in range5) {
		println("yes")
	}
	if (12 !in range5) {
		println("no")
	}
}
```

---

### N.B.

L'argomento relativo a funzioni, cicli ed espressioni sarà approfondito più avanti.

---

### Funzioni (functions)

Le funzioni in Kotlin vengono sempre create **mediante il comando *fun***. Dopodiché vengono definiti il nome della funzione, gli argomenti contenuti e il modo in cui agisce.

```none
fun div(a: Int, b: Int): Int {
	return a/b
}
fun main() {
	println(div(100, 2))
}
```

Innanzitutto definiamo la funzione *div* (che sta per divisione) mediante due parametri Int, *a* e *b*. Compito della funzione è quello di fornirci il risultato della divisione tra a e b, sempre sotto forma di variabile Int. In seguito chiamiamo la funzione precedentemente definita nella funzione *main*, le assegniamo valori concreti e visualizziamo il risultato nella console mediante *println* (print line). Kotlin esegue il contenuto della funzione *main()* automaticamente. Questa funzione rappresenta il punto di partenza in un programma Kotlin.

---

### Fatto

Kotlin non accetta comandi oltre alle funzioni. Sono ammesse solo dichiarazioni.

---

In Kotlin è possibile rappresentare le funzioni composte da una sola riga di codice **in modo semplificato**. Invece di aprire una parentesi graffa, scrivere una nuova riga e chiudere la parentesi, si usa un segno uguale e si rinuncia al comando *return*.

```none
fun div(a: Int, b: Int): Int = a/b
fun main() = println(div(100, 2))
```

Quando definite una funzione potete indicare valori di default per evitare che parametri mancanti causino errori. In questo modo se lasciate vuoti i rispettivi parametri, verranno utilizzati i **valori di default**.

```none
fun div(a: Int = 10, b: Int = 5): Int = a/b
fun main() = println(div())
```

### Lambda

Una funzione lambda (o funzione anonima) è una funzione che non appartiene ad alcuna classe o oggetto. Le funzioni lambda **vengono inserite direttamente in altre funzioni o variabili** e chiamate senza l'uso della keyword *fun*. Le funzioni lambda vengono sostanzialmente utilizzate e create come le variabili del tipo *val*.

```none
fun main() {
	val myMessage = { println("Hello world!") }
	myMessage()
}
```

In Kotlin le espressioni lambda devono essere inserite sempre tra parentesi graffe e possono elaborare anche argomenti di funzioni. Queste sono contrassegnate da una **freccia** che separa i parametri dal nucleo dell'espressione.

```none
fun main() {
    val div = {a: Int, b: Int -> a/b}
    println(div(6,2))
}
```

### Classi (classes)

Proprio come in Java, anche in Kotlin le classi sono **raccolte di dati e funzioni**. Per definire una classe è sufficiente inserire la keyword *class*. In seguito è possibile aggiungere informazioni alla classe.

```none
class Tardis {
	var year: Int
	var place: String
	constructor(year: Int, place: String) {
		this.year = year
		this.place = place
	}
}
```

In Kotlin il costruttore rappresenta una funzione necessaria per la creazione di oggetti. A tale scopo il linguaggio di programmazione distingue tra **costruttori primari e secondari.** I costruttori primari sono una pratica scrittura abbreviata, mentre quelli secondari ricordano molto la scrittura di altri linguaggi a oggetti, come Java. L'esempio summenzionato mostra la seconda variante.

È possibile comunque omettere il costruttore secondario e inserire al suo posto un costruttore primario, che viene specificato direttamente nell'intestazione della classe e ne indica, allo stesso tempo, i parametri, riducendo notevolmente il numero di righe di codice.

```none
class Tardis constructor(var year: Int, var place: String)
```

Se non volete specificare ulteriori istruzioni in merito alla visibilità (public, private, protected), potete omettere del tutto la keyword.

```none
class Tardis (var year: Int, var place: String)
```

Tutti e tre gli esempi di codice restituiscono lo stesso risultato.

Potete adesso inserire la classe nel resto del vostro testo sorgente e alimentarla con valori concreti.

```none
val tardis1 = Tardis(2133, "Dunlop Station")
val tardis2 = Tardis(1885, "Northhampton")
```

Come per la maggior parte dei linguaggi a oggetti potete accedere alle proprietà e ai metodi di un oggetto posizionando un punto e il nome della proprietà o del metodo dopo quello dell'oggetto stesso.

```none
class Tardis (var year: Int, var place: String)
val tardis1 = Tardis(2133, "Dunlop Station")
val tardis2 = Tardis(1885, "Northhampton")
fun main() {
    println(tardis1.year)
}
```

Una particolarità di Kotlin sono le **data class**. Questo tipo di classe ha l'unico scopo di immagazzinare dati. A tale scopo è, in genere, sufficiente una riga di codice.

```none
data class User (var username: String, var name: String, var age: Int)
```

Questa classe può essere utilizzata direttamente.

```none
data class User (var username: String, var name: String, var age: Int)
fun main() {
    val user1 = User ("River Song", "Melody Pond", 200)
    println("Username: " + user1.username)
    println("Name: " + user1.name)
    println("Age: " + user1.age)
}
```

### Oggetti (objects)

In Kotlin gli oggetti sono istanze che possono essere definite in un determinato modo una sola volta (singleton). In genere **contengono variabili e funzioni**. Per creare un oggetto è solitamente sufficiente una sola riga di codice, come anche per le classi. L'oggetto creato sarà comunque vuoto e i relativi contenuti saranno aggiunti al suo corpo.

```none
object myObject {
	fun sum(a: Int, b: Int): Int {
		return a+b
	}
}
```

### Cicli (loop)

In Kotlin potete scegliere tra tre diverse tipologie di ciclo: *while*, *do..while* e *if*, che si comportano esattamente come le loro controparti in altri linguaggi di programmazione. Un **ciclo di tipo** ***while*** viene eseguito finché una determinata condizione resta verificata.

```none
fun main() {
    var n = 1
    while (n <= 10) {
        println(n++)
    }
}
```

Il **ciclo *do..while*** si comporta in modo analogo a quello con *while*. La differenza sta nel fatto che in questo caso il ciclo viene eseguito almeno una volta, dato che il controllo della condizione viene eseguito soltanto al termine del ciclo.

```none
fun main() {
    var n = 1
    do {
        n++
    }	
    while (n < 1)
    println(n)
}
```

Il **ciclo** ***for*** viene eseguito finché la condizione è vera.

```none
val myRange = 0..10
fun main() {
	for (n in myRange) {
		print("$n ")
	}
}
```

### Condizioni (conditions)

Kotlin adotta tre diverse possibilità per eseguire istruzioni o diramazioni condizionali: *if*, *if..else* e *when*. Mediante l'espressione ***if***, il computer esegue un'istruzione se la condizione è vera.

```none
val whoCompanion = arrayOf("Bill Potts", "Clara Oswald", "Amy Pond", "Martha Jones", "Donna Noble", "Rose Tyler")
fun main() {
    if ("Rose Tyler" in whoCompanion) {
        print("yes")
    }
}
```

Con ***else*** aggiungete un'azione che deve essere eseguita qualora la condizione non fosse vera.

```none
val whoCompanions9 = arrayOf("Rose Tyler")
val whoCompanions10 = arrayOf("Martha Jones", "Donna Noble", "Rose Tyler")
val whoCompanions11 = arrayOf("Clara Oswald", "Amy Pond")
val whoCompanions12 = arrayOf("Bill Potts", "Clara Oswald")
fun main() {
    var whoCompanion = "Clara Oswald"
    if (whoCompanion in whoCompanions9) {
        print("yes")
    }
    else {
        print("no")
    }
}
```

Infine l'espressione ***when*** è una particolarità di Kotlin: a seconda delle condizioni vengono eseguite azioni diverse. L'espressione *when* somiglia quindi a quello che in altri linguaggi di programmazione viene definito *switch*, ma lavora in modo più preciso.

Nel corpo di *when* inserite i diversi casi di controllo, che sono sempre collegati a una determinata variabile.

```none
var age = 17
fun main() {
    when {
     	age > 18 -> println("Sei troppo grande!")
     	age == 18 -> println("Già adulta!")
     	age == 17 -> println("Benvenuta!")
     	age <= 16 -> println("Sei troppo giovane!")
    }
}
```

Se l'argomento viene trasferito direttamente a *when* non è necessario ripeterlo ogni volta nel corpo. Una **singola condizione può inoltre eseguire diverse azioni**. A tale scopo, create mediante parentesi graffe un nuovo corpo e per evitare casi inaspettati utilizzate *else*.

```none
fun multi(a: Int, b: Int, c: Int): Int {
    return a*b*c
}
fun main() {
    val d = "yes"
    when (d) {
        "no" -> println("Nessun calcolo")
        "yes" -> {
            println("Avvia calcolo") 
            println(multi(5, 2, 100))
            println("Calcolo terminato")
        }
    else -> println("Inserimento errato")    
    }
}
```

### Nullabilità

Un aspetto molto scoraggiante nella programmazione con Java è l'**errore *NullPointerException***, che si presenta quando si chiama un oggetto con valore *null*. Kotlin aggira questo problema impedendo di default alle variabili di assumere il valore *null*. Se si verificasse questa condizione, comparirebbe già durante la compilazione la seguente nota: "Null can not be a value of a non-null type String" o un avviso simile.

Ci sono però momenti in cui si intende utilizzare il valore *null* intenzionalmente. Per questi casi, Kotlin utilizza l'**operatore di chiamata sicura** *?.*

```none
fun main() {
	var password: String? = null
	print(password)
}
```

In questo modo indicate esplicitamente a Kotlin che il valore *null* è ammissibile. Il programma restituisce *null*. Se invece volete indirizzare una proprietà particolare della variabile, dovete nuovamente ricorrere all'operatore di chiamata sicura.

```none
fun main() {
	var password: String? = null
	print(password?.length)
}
```

Anche questo codice restituirà *null*, ma senza produrre errori o compromettere il funzionamento del programma. Un modo più elegante sarebbe indicare un valore alternativo. A tale scopo potete usare l'**operatore elvis** *(?:)*, così chiamato per la sua somiglianza a una faccina sorridente con il ciuffo.

```none
fun main() {
    val firstName = null
    val lastName = "Pond"
	val name: String = firstName?: "Nome mancante" + " " + lastName?: "Cognome mancante"
	print(name)
}
```

In questo esempio vengono visualizzate delle note nel caso in cui una variabile abbia il valore *null*.


This is a markdown version of: [https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/tutorial-kotlin/](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/tutorial-kotlin/) for AI/LLM consumption.