Capitolo 2

Variabili, costanti e i tipi di dato

Un programma deve ricordare dei dati: il prezzo di un prodotto, il punteggio di un gioco, il nome dell'utente. Per farlo usa le variabili (che cambiano) e le costanti (che restano uguali). Imparerai anche i tipi di dato e come inserire i valori dentro al testo.

In questo capitolo impari

Ripasso lampo: quello che serve prima di partire

Rispondi a memoria, poi controlla con il capitolo 1 se sbagli.

Che cosa stampa questo programma?

fun main() {
    println("A")
    print("B")
    println("C")
}
A, B, C su tre righeNo: print("B") non va a capo, quindi C finisce sulla stessa riga.
A poi BCEsatto: println("A") va a capo, print("B") resta sulla riga, println("C") chiude la riga.
ABC tutto su una rigaIl primo comando è println, quindi dopo la A c'è un ritorno a capo.

Il comando dice dove finisce la riga: println va a capo dopo aver stampato, print no. La differenza si vede solo nell'output, mai nel codice.

Quale riga fa apparire un errore?

println("Ciao mondo!")Questa è corretta: il testo è fra virgolette doppie.
println('Ciao mondo!')Esatto: l'apice singolo serve per un solo carattere. Per una frase servono le virgolette doppie.
// println("Ciao mondo!")Questa non dà errore: è un commento, quindi il computer la ignora.

Le virgolette doppie racchiudono il testo ("ciao"). L'apice singolo racchiude un solo carattere ('c'): il capitolo 1 lo ha già detto, e in questo capitolo gli dai anche un nome, Char.

2.1 var: variabili che cambiano

Una variabile si crea con var, poi si scrive il nome e con = il valore iniziale. Da quel momento il nome è come una scatola con dentro il valore: puoi cambiarlo scrivendo di nuovo nome = nuovoValore.

La scrittura punti = punti + 5 si legge in un colpo solo: «il nuovo valore di punti è quello di prima, più 5». In questo manuale useremo sempre questa forma estesa, perché rende visibile che cosa succede al valore della variabile. Nei programmi Kotlin che incontrerai altrove esistono anche le scorciatoie punti += 5 e punti++: significano esattamente la stessa cosa, ma qui preferiamo la forma che si spiega da sola.

  1. accessi = accessi + 1 due volte porta la variabile da 0 a 2.
  2. totale = totale + 50 porta 100 a 150; poi totale = totale - 30 lo porta a 120.
  3. In ogni aggiornamento il lato destro usa il valore che la variabile aveva fino a quel momento, e il risultato diventa il valore nuovo.
  4. Nel codice vero e proprio incontrerai anche le scorciatoie accessi++ e totale += 50: fanno esattamente quello che fanno le forme estese qui sopra.

2.2 val: costanti che non cambiano

Quando un valore non deve cambiare durante il programma si usa val. Se più avanti provi a modificarlo, Kotlin ti avvisa con un errore: è una cosa voluta, perché protegge il programma dagli errori.

Esegui e osserva il pannello Variabili

Sotto la console vedi la tabella delle variabili: val nome e val annoNascita con il loro tipo e valore. Decommenta la riga nome = "Marco" per vedere l'errore: «"nome" è una costante (val)».

var o val? Regola pratica

Parti sempre da val. Passa a var solo quando il valore deve davvero cambiare (contatori, somme accumulate, punteggi). Un programma con pochi var è più facile da capire.

2.3 I tipi di dato

Ogni valore ha un tipo: dice che cosa è quel valore e che cosa ci si può fare. Non è una formalità da imparare a memoria, è quello che decide come si comporta il programma. Guarda questi due programmi: scrivono quasi la stessa cosa, ma il risultato è diverso.

3 è un numero e si somma; "3", con le virgolette, è testo e i testi si incollano l'uno all'altro. Le virgolette doppie cambiano tutto: è il tipo che decide.

Il tipo lo decide il valore, e si riconosce dalla forma: senza virgolette è un numero; fra virgolette doppie è testo; fra apici singoli è un solo carattere; true e false sono un sì-o-no. Kotlin guarda la forma e capisce da solo di che tipo si tratta. I tipi che useremo sono cinque. Il pannello delle variabili ti mostra quello che Kotlin ha capito. Nella sezione dopo vediamo quando conviene scrivere il tipo a mano.

TipoCosa contieneEsempi
Intnumeri interi5, -12, 0
Doublenumeri con la virgola (in Kotlin il punto)3.5, -0.25
Stringtesto fra virgolette doppie"ciao", "5C"
Booleansolo due valori: vero o falsotrue, false
Charun singolo carattere, fra apici singoli'a', '5'

2.4 Dichiarare il tipo con i due punti

Il tipo puoi anche scriverlo tu, con i due punti dopo il nome, come in val media: Double = 7.5. Non è obbligatorio: Kotlin lo deduce già dal valore. Serve in due casi.

Con media il 7 resta intero e la divisione butta via i decimali; con mediaEsatta il 7 diventa 7.0 e la divisione tiene i decimali. Un numero intero entra in un Double senza problemi: anche val prezzo: Double = 5 stampa 5.0. È il contrario che non funziona — scrivere val quantita: Int = 3.5 è un errore, perché 3.5 non entra in un intero.

2.5 Il tipo non cambia più

C'è una cosa che sorprende: una volta deciso, il tipo non cambia più. var ti lascia cambiare il valore, non il tipo. var quantita = 3 potrà valere 5, 10, 100 — sempre un numero intero. Se provi a metterci del testo, il programma si ferma e te lo dice.

L'avviso arriva subito, sulla riga che hai scritto, e nomina i due tipi in gioco: «è dichiarata di tipo Int ma stai assegnando un valore di tipo String». È il tipo che ti protegge: se il controllo non ci fosse, quantita = "tre" passerebbe e il programma darebbe risultati strani molto più tardi, in un punto da cui non capiresti più da dove viene il guaio.

Il tipo e var/val sono due domande diverse

var o val risponde a «il valore può cambiare?». Il tipo risponde a «che cosa contiene?». Le due cose sono indipendenti: var punti = 0 è un Int che può cambiare valore, val punti = 0 è un Int che non può cambiarlo — ma in entrambi i casi resta un numero intero, e in nessuno dei due potrà contenere del testo.

Int e Double non si mescolano da soli

5 / 2 fa 2, perché sono due numeri interi e la parte decimale viene persa. Per ottenere 2.5 serve almeno un numero con la virgola: 5.0 / 2 oppure 5 / 2.0.

  1. 7 / 2 è una divisione fra Int: il risultato è 3, la parte decimale viene tagliata (non arrotondata).
  2. 7.0 / 2 ha un Double, quindi il risultato è decimale: 3.5.
  3. 7 % 2 dà il resto: 1.
  4. L'ultima riga non fa conti: "7" è testo, quindi + attacca i due valori e ottieni 72. Se ti aspettavi 9, serviva "7".toInt() + 2.

2.6 I template di stringa: mettere i valori nel testo

Invece di unire i pezzi con +, puoi scrivere il nome della variabile dentro alla stringa usando il simbolo $. Si chiama template di stringa. Per espressioni più complesse si usano le graffe: ${espressione}.

  1. Dentro ${...} ci sta una vera espressione: Kotlin calcola 3 * 6.5 e poi inserisce il risultato nel testo.
  2. Il risultato è 19.5, un Double: nella console i decimali si vedono con il punto, non con la virgola.
  3. La seconda espressione riusa gli stessi valori: 19.5 - 5 = 14.5.
Quando servono le graffe

"$nome" funziona, ma "$nomeciao" fa cercare una variabile chiamata nomeciao (che non esiste). In casi come questi si scrive "${nome}ciao". Per stampare un dollaro letterale si usa \$.

2.7 Le operazioni

Le operazioni si scrivono come in matematica: + somma, - sottrae, * moltiplica, / divide, % dà il resto. Le parentesi decidono l'ordine, come a scuola.

In questo programma, di che tipo è ore?

fun main() {
    val minutiTotali = 137
    val ore = minutiTotali / 60
}
Double, perché 137 / 60 fa 2.28No: sono due interi. La parte decimale viene tagliata: ore vale 2.
IntEsatto: divisione fra interi. Il risultato è 2, senza virgola.
StringNo: non ci sono virgolette. È un conto, non un testo.

Il tipo lo decide il valore. 137 e 60 sono interi, quindi anche 137 / 60. Per i decimali serve almeno un numero con il punto, come 137.0 / 60.

2.8 Cambiare tipo a un valore (conversioni)

Un testo come "42" è una String, non un numero: per fare conti serve convertirlo. Le conversioni più usate sono toInt(), toDouble() e toString() (quest'ultima trasforma un numero in testo).

Che cosa stampa questo programma?

fun main() {
    println("42" + 8)
}
50No: "42" è testo, quindi + non somma, attacca.
428Esatto: il testo "42" e il numero 8 vengono uniti in un'unica stringa.
Un errore, perché non si possono sommare testo e numeroKotlin non dà errore: trasforma il numero in testo e unisce i due pezzi.

Per sommare davvero serve convertire: "42".toInt() + 8 dà 50.

Il caso più frequente con le conversioni

Sommare un numero intero a un Double va bene (1 + 2.5 fa 3.5), ma sommare due Int e sperare in un decimale non funziona: converti prima uno dei due con .toDouble().

2.9 Riepilogo

ScriviSignificato
var punti = 0variabile intera che può cambiare
val nome = "Anna"costante di testo, non si modifica più
val prezzo: Double = 3.5costante con tipo dichiarato
val media = 7 / val media: Double = 7senza tipo è un Int; dichiarandolo Double vale 7.0
var x = 3 poi x = "tre"errore: il tipo è deciso dalla prima assegnazione e non cambia più
punti = punti + 5, punti = punti + 1aggiorna la variabile usando il suo valore di prima
"Ciao $nome"template: inserisce il valore nella stringa
"${a * b}"template con espressione
"5".toInt(), 5.toString()conversioni fra testo e numeri

2.10 Esercizi guidati

Un negozio vende quaderni a 2.50 euro e penne a 1.25 euro. Usando delle costanti val per i prezzi e delle variabili var per le quantità, calcola e stampa tre righe: il totale dei quaderni, il totale delle penne e il totale generale. Con 4 quaderni e 3 penne le tre righe sono Quaderni: 10.0 euro, Penne: 3.75 euro e Totale: 13.75 euro.

Il totale dei quaderni è quantitaQuaderni * prezzoQuaderno. Crea delle val per i due subtotali e poi sommale per il totale generale.

  1. I prezzi non cambiano durante il programma, quindi sono val: così non si possono modificare per sbaglio.
  2. Le quantità potrebbero cambiare (magari l'utente le legge da input nel capitolo 3), quindi sono var.
  3. quantitaQuaderni * prezzoQuaderno moltiplica un Int per un Double: il risultato è un Double, perché basta un numero con la virgola per rendere decimale il risultato.
  4. Nel template "Quaderni: $totaleQuaderni euro" le graffe non servono: dopo il dollaro c'è il nome della variabile e poi uno spazio.

Dato un numero di secondi (per esempio 3725), calcola quante ore, quanti minuti e quanti secondi rappresentano. Usa la divisione intera e l'operatore resto %. Con 3725 la riga da stampare è 3725 secondi = 1 ore, 2 minuti e 5 secondi.

Un'ora ha 3600 secondi, un minuto 60. Le ore si ottengono con secondiTotali / 3600, poi quello che avanza si lavora con % 3600.

  1. secondiTotali / 3600 è una divisione fra interi: 3725 / 3600 fa 1, la parte decimale viene tagliata via.
  2. % 3600 restituisce il resto, cioè i secondi che non formano un'ora intera: 3725 % 3600 = 125.
  3. Con quei 125 secondi si ripete lo stesso ragionamento con i minuti: 125 / 60 = 2 minuti e 125 % 60 = 5 secondi.
  4. Questo schema (dividere e poi usare il resto) si usa ogni volta che serve scomporre una quantità in unità più piccole: euro e centesimi, metri e centimetri, ore e minuti.

Crea le variabili di un personaggio di un videogioco: nome (String), livello (Int), punti vita (Int), velocità (Double) e se ha la spada (Boolean). Poi: aumenta il livello di 1, togli 15 punti vita, raddoppia la velocità e stampa una scheda finale con tutti i valori in quest'ordine, usando i template di stringa: una riga titolo === SCHEDA PERSONAGGIO ===, poi nome, livello, punti vita, velocità e spada. Dopo le modifiche i valori sono Zorro, 5, 85, 7.0 e true.

Per aumentare il livello scrivi livello = livello + 1. Per togliere punti vita: puntiVita = puntiVita - 15. Per raddoppiare la velocità: velocita = velocita * 2.

  1. livello = livello + 1 aumenta di uno: passa da 4 a 5.
  2. puntiVita = puntiVita - 15 toglie 15 ai punti vita: 100 diventa 85.
  3. velocita = velocita * 2 funziona anche con i Double: 3.5 diventa 7.0 (nella console il numero decimale si vede con il punto).
  4. haLaSpada resta true perché è una val: il personaggio può perdere punti vita, ma non la spada.

Questo programma deve stampare il totale di 3 quaderni e il prezzo con lo sconto del 10%, ma non funziona. Eseguilo, leggi il messaggio di errore e correggi un errore alla volta: alla fine deve stampare due righe, Totale: 7.5 euro e Scontato: 6.75 euro.

Tre cose non vanno: manca la parola val o var davanti a totale; i decimali si scrivono con il punto, non con la virgola; il nome di una variabile va scritto sempre uguale (controlla scontato/scontado).

  1. 0,9 con la virgola: Kotlin vuole il punto per i decimali. È l'errore che vedi per primo, perché la punteggiatura viene controllata prima di eseguire.
  2. totale = prezzo * quantita senza val o var: Kotlin non sa che stai creando una variabile nuova, quindi non la trova.
  3. prezzo = 2.00: prezzo è una val e non si può riassegnare. Nel programma corretto la riga non serve.
  4. scontado non esiste: il nome dichiarato è scontato, e Kotlin distingue ogni lettera.
  5. Il risultato finale sono due righe: Totale: 7.5 euro e Scontato: 6.75 euro.
  • so scegliere fra var e val e so spiegare perché
  • so aggiornare una variabile usando il suo valore di prima, come in punti = punti + 5, e so riconoscere le scorciatoie += e ++
  • so riconoscere i tipi Int, Double, String, Boolean, Char, e so che cosa li distingue dalla forma del valore
  • so spiegare perché una variabile non può cambiare tipo, e che cosa serve dichiararlo con i due punti
  • so prevedere quando una divisione dà un risultato intero e quando decimale
  • so inserire un valore dentro una stringa con $nome e ${espressione}
  • so usare % per ottenere il resto e so convertire con toInt(), toDouble(), toString()
  • so leggere un messaggio di errore e correggere il programma da solo