Kotlin Cheat Sheet
Ultimo aggiornamento
Hello World e basi
Un programma Kotlin parte da una funzione main di primo livello, senza bisogno di una classe.
| Sintassi | Significato |
|---|---|
fun main() { println("Hello") } | Punto di ingresso del programma |
println("text") | Stampare una riga sullo standard output |
print("text") | Stampare senza andare a capo |
// comment | Commento su una riga |
/* comment */ | Commento su più righe |
val input = readLine() | Leggere una riga da stdin (String? nullable) |
val line = readln() | Leggere una riga da stdin (non null, Kotlin 1.6+) |
Variabili (val / var) e tipi
Preferisci val; usa var solo quando il valore deve cambiare.
| Sintassi | Significato |
|---|---|
val name = "Ada" | Variabile di sola lettura, tipo dedotto come String |
var count = 0 | Variabile modificabile |
val age: Int = 30 | Annotazione di tipo esplicita |
Int, Long, Double, Float | Tipi numerici (42, 42L, 3.14, 3.14f) |
Boolean, Char, String | true/false, 'a', "text" |
val big = 1_000_000 | Underscore per letterali più leggibili |
"3".toInt(), "2.5".toDouble() | Convertire una stringa in numero |
42.toString() | Da numero a stringa |
const val MAX = 10 | Costante a tempo di compilazione (a livello top o in un object) |
Stringhe e template
Gli string template sostituiscono la concatenazione quasi ovunque.
| Sintassi | Significato |
|---|---|
"Hi, $name" | Inserire una variabile in una stringa |
"Total: ${price * qty}" | Inserire un'espressione |
s.length | Numero di caratteri |
s.uppercase(), s.lowercase() | Cambiare maiuscole e minuscole |
s.trim() | Rimuovere gli spazi iniziali e finali |
s.contains("x"), s.startsWith("a") | Cercare dentro una stringa |
s.substring(0, 3) | Porzione per intervallo di indici |
s.split(",") | Dividere in una List<String> |
s[0] | Carattere a un indice |
"""raw text""" | Stringa grezza su più righe, senza escape |
"%.2f".format(3.14159) | Output formattato (3.14) |
Null safety
Un tipo è non null per impostazione predefinita; aggiungi ? per permettere null e il compilatore ti obbliga a gestirlo.
| Sintassi | Significato |
|---|---|
var s: String? = null | Tipo nullable |
s?.length | Safe call: restituisce null se s è null |
s?.length ?: 0 | Operatore Elvis: valore di riserva quando è null |
s!!.length | Asserzione not-null: lancia un'eccezione se s è null |
if (s != null) s.length | Smart cast a non null dentro il controllo |
s?.let { println(it) } | Eseguire un blocco solo se non è null |
val n = s?.toIntOrNull() | Convertire, oppure null se l'input non è valido |
lateinit var x: String | Var non null inizializzata in seguito |
Operatori
| Operatore | Significato |
|---|---|
+ - * / % | Aritmetici (/ tra Int è divisione intera) |
+= -= *= /= %= | Assegnazione composta |
++ -- | Incremento / decremento |
== != | Uguaglianza strutturale (chiama equals) |
=== !== | Uguaglianza referenziale (stesso oggetto) |
< > <= >= | Confronto |
&& || ! | And / or / not logici |
a in 1..10 | Appartenenza a un range o a una collezione |
x as Int, x as? Int | Cast / cast sicuro (null se fallisce) |
x is String | Controllo di tipo (smart cast se riesce) |
Controllo del flusso (if / when)
if e when sono espressioni: restituiscono un valore.
| Sintassi | Significato |
|---|---|
if (a > b) x else y | if come espressione (Kotlin non ha il ternario ?:) |
if (c) { ... } else if (d) { ... } else { ... } | Rami concatenati |
when (x) { 1 -> "one"; 2 -> "two"; else -> "other" } | Confrontare un valore |
when (x) { 1, 2 -> "low" } | Più valori in un solo ramo |
when (x) { in 1..9 -> "digit" } | Confrontare con un range |
when (x) { is String -> x.length } | Confrontare il tipo (con smart cast) |
when { x < 0 -> "neg"; x == 0 -> "zero"; else -> "pos" } | when senza soggetto, come if/else if |
val label = when (x) { ... } | when come espressione (serve else) |
Cicli e range
| Sintassi | Significato |
|---|---|
for (i in 1..5) | Range inclusivo da 1 a 5 |
for (i in 1 until 5) | Da 1 a 4 (fine esclusa) |
for (i in 0..<5) | Uguale, con la sintassi del range aperto (Kotlin 1.9+) |
for (i in 10 downTo 1 step 2) | Conto alla rovescia a passi |
for (item in list) | Iterare una collezione |
for ((i, item) in list.withIndex()) | Indice ed elemento insieme |
for (ch in "abc") | Iterare i caratteri di una stringa |
while (cond) { ... } | Ciclare finché è vero |
do { ... } while (cond) | Eseguire almeno una volta |
break, continue | Uscire dal ciclo / passare all'iterazione successiva |
repeat(3) { println(it) } | Eseguire un blocco n volte |
Funzioni
| Sintassi | Significato |
|---|---|
fun add(a: Int, b: Int): Int { return a + b } | Dichiarare una funzione |
fun add(a: Int, b: Int) = a + b | Funzione a espressione singola, tipo di ritorno dedotto |
fun greet(name: String = "world") | Valore predefinito di un parametro |
greet(name = "Ada") | Argomento con nome |
fun log(vararg items: String) | Numero variabile di argomenti |
fun say(): Unit | Nessun valore di ritorno (Unit è opzionale) |
val square = { x: Int -> x * x } | Lambda salvata in una variabile |
fun String.shout() = uppercase() + "!" | Funzione di estensione |
fun apply(f: (Int) -> Int) = f(2) | Funzione come parametro |
list.map { it * 2 } | Trailing lambda, it è l'unico parametro |
Liste
listOf è di sola lettura; mutableListOf si può modificare.
| Sintassi | Significato |
|---|---|
val nums = listOf(1, 2, 3) | Lista di sola lettura |
val items = mutableListOf("a") | Lista modificabile |
nums[0], nums.first(), nums.last() | Accedere agli elementi |
nums.getOrNull(9) | Accesso sicuro, null se fuori intervallo |
items.add("b"), items.remove("a") | Aggiungere / rimuovere |
items[0] = "z" | Sostituire per indice |
nums.size, nums.isEmpty() | Dimensione e verifica se è vuota |
x in nums, nums.contains(x) | Appartenenza |
nums.indexOf(2) | Posizione di un elemento, -1 se assente |
nums.subList(0, 2) | Porzione (fine esclusa) |
nums.take(2), nums.drop(1) | Primi n / tutti tranne i primi n |
nums.sorted(), nums.reversed() | Nuova lista ordinata / invertita |
nums.sum(), nums.average(), nums.maxOrNull() | Aggregati |
nums.joinToString(", ") | Unire in un'unica stringa |
Pair(1, "a"), 1 to "a", Triple(1, 2, 3) | Piccole tuple fisse |
Map e set
| Sintassi | Significato |
|---|---|
val m = mapOf("a" to 1, "b" to 2) | Map di sola lettura |
val mm = mutableMapOf<String, Int>() | Map modificabile |
m["a"] | Ricerca (null se manca) |
m.getOrDefault("z", 0) | Ricerca con valore di riserva |
mm["c"] = 3 | Inserire o aggiornare |
for ((k, v) in m) | Iterare le voci con il destructuring |
m.keys, m.values | Collezioni di chiavi / valori |
"a" in m | Presenza di una chiave |
val s = setOf(1, 2, 2) | Set di valori unici ({1, 2}) |
mutableSetOf<Int>() | Set modificabile |
Operazioni sulle collezioni (lambda)
| Sintassi | Significato |
|---|---|
list.map { it * 2 } | Trasformare ogni elemento |
list.filter { it > 2 } | Tenere gli elementi che corrispondono |
list.forEach { println(it) } | Fare qualcosa con ciascuno |
list.any { it > 2 }, list.all { it > 0 } | Qualche / ogni elemento corrisponde |
list.count { it % 2 == 0 } | Contare le corrispondenze |
list.find { it > 2 } | Prima corrispondenza oppure null |
list.sortedBy { it.length } | Ordinare in base a una chiave |
list.groupBy { it.first() } | Raggruppare in una Map |
list.distinct() | Rimuovere i duplicati |
list.fold(0) { acc, x -> acc + x } | Ridurre con un valore iniziale |
list.zip(other) | Accoppiare due liste |
list.flatMap { it.toList() } | Mappare e poi appiattire |
Classi e data class
| Sintassi | Significato |
|---|---|
class User(val name: String, var age: Int) | Classe con costruttore primario e proprietà |
val u = User("Ada", 36) | Creare un'istanza (senza new) |
u.name, u.age = 37 | Leggere / scrivere proprietà |
data class Point(val x: Int, val y: Int) | equals, hashCode, toString, copy gratis |
p.copy(y = 5) | Copiare cambiando alcune proprietà |
val (x, y) = p | Dichiarazione con destructuring |
open class Base, class Sub : Base() | Ereditarietà (le classi sono final per impostazione predefinita) |
override fun toString() = "..." | Sovrascrivere un membro |
object Config { val debug = true } | Singleton |
companion object { fun create() = User("", 0) } | Membri simili a static |
enum class Color { RED, GREEN } | Enum |
sealed class Result | Gerarchia di classi ristretta, esaustiva in when |
interface Shape { fun area(): Double } | Interfaccia |
Gestione degli errori
| Sintassi | Significato |
|---|---|
try { ... } catch (e: Exception) { ... } | Catturare un'eccezione |
try { ... } finally { ... } | Eseguire sempre la pulizia |
val n = try { s.toInt() } catch (e: NumberFormatException) { 0 } | try come espressione |
throw IllegalArgumentException("bad") | Lanciare un'eccezione |
require(x > 0) { "x must be positive" } | Controllo sugli argomenti (lancia IllegalArgumentException) |
check(ready) { "not ready" } | Controllo sullo stato (lancia IllegalStateException) |
s.toIntOrNull() | Restituire null invece di lanciare un'eccezione |
runCatching { risky() }.getOrDefault(0) | Racchiudere una chiamata in un Result |
Scope function
Cinque piccoli helper per lavorare con un oggetto dentro un blocco.
| Sintassi | Significato |
|---|---|
x.let { it + 1 } | it è l'oggetto, restituisce il risultato del blocco |
x.run { this + 1 } | this è l'oggetto, restituisce il risultato del blocco |
x.apply { field = 1 } | this è l'oggetto, restituisce l'oggetto |
x.also { println(it) } | it è l'oggetto, restituisce l'oggetto |
with(x) { field } | Non è un'estensione; this è x, restituisce il risultato del blocco |
x?.let { ... } | Il modo idiomatico per controllare null e usare il valore |
Tutta la sintassi di Kotlin che usi, in una sola pagina. Questa cheat sheet di Kotlin è un riferimento rapido per il linguaggio dietro Android e buona parte della JVM moderna: dichiarare variabili, gestire i null in sicurezza, ramificare con when, ciclare sui range, scrivere funzioni e lavorare con liste e map.
Tutto quello che trovi qui è Kotlin standard e gira allo stesso modo su JVM, Android e Kotlin Multiplatform. Copia quello che ti serve oppure provalo dal vivo nel playground Kotlin: incolla un frammento, premi Run e guarda l'output nel browser.
Domande frequenti sulla cheat sheet di Kotlin
Questa cheat sheet di Kotlin è gratuita?
when, un operatore di null safety o un metodo delle collezioni.Qual è la differenza tra val e var in Kotlin?
val dichiara un riferimento di sola lettura: viene assegnato una volta e non si può riassegnare. var dichiara una variabile modificabile che si può riassegnare. Nota che val blocca solo il riferimento: a una val list = mutableListOf(1) puoi comunque aggiungere elementi. Lo stile Kotlin prevede di usare val ovunque e passare a var solo quando serve davvero riassegnare.Come funziona la null safety in Kotlin?
String non può mai contenere null, mentre String? sì. Il compilatore non ti lascia chiamare un metodo su un valore nullable senza gestire il caso null: con una safe call (s?.length), un valore di riserva con Elvis (s?.length ?: 0), un controllo null che fa smart cast (if (s != null)) o, come ultima risorsa, l'asserzione not-null s!!, che lancia una NullPointerException se il valore è davvero null.Quando usare when invece di if in Kotlin?
when ogni volta che confronti un valore con diverse possibilità (costanti, range, tipi o un mix) e usa if/else per una singola condizione sì o no. Sono entrambe espressioni, quindi val label = when (x) { ... } e val label = if (c) a else b sono entrambe idiomatiche. Un when usato come espressione deve essere esaustivo, il che di solito significa aggiungere un ramo else (sealed class ed enum possono essere esaustive anche senza).Posso esercitarmi con Kotlin online?
when, cicli, funzioni e collezioni, e alla fine ti rilascia un certificato gratuito.