Anteprima
Vedrai una selezione di 10 pagine su 42
Kotlin - Appunti dettagliati con esempi di codice (42 pagine) Pag. 1 Kotlin - Appunti dettagliati con esempi di codice (42 pagine) Pag. 2
Anteprima di 10 pagg. su 42.
Scarica il documento per vederlo tutto.
Kotlin - Appunti dettagliati con esempi di codice (42 pagine) Pag. 6
Anteprima di 10 pagg. su 42.
Scarica il documento per vederlo tutto.
Kotlin - Appunti dettagliati con esempi di codice (42 pagine) Pag. 11
Anteprima di 10 pagg. su 42.
Scarica il documento per vederlo tutto.
Kotlin - Appunti dettagliati con esempi di codice (42 pagine) Pag. 16
Anteprima di 10 pagg. su 42.
Scarica il documento per vederlo tutto.
Kotlin - Appunti dettagliati con esempi di codice (42 pagine) Pag. 21
Anteprima di 10 pagg. su 42.
Scarica il documento per vederlo tutto.
Kotlin - Appunti dettagliati con esempi di codice (42 pagine) Pag. 26
Anteprima di 10 pagg. su 42.
Scarica il documento per vederlo tutto.
Kotlin - Appunti dettagliati con esempi di codice (42 pagine) Pag. 31
Anteprima di 10 pagg. su 42.
Scarica il documento per vederlo tutto.
Kotlin - Appunti dettagliati con esempi di codice (42 pagine) Pag. 36
Anteprima di 10 pagg. su 42.
Scarica il documento per vederlo tutto.
Kotlin - Appunti dettagliati con esempi di codice (42 pagine) Pag. 41
1 su 42
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

Array

di ogni elemento del vettore per ogni dato indice. Alcuni esempi nel listato 13:

val a r r a y = a r r a y O f ( 1 , 2 , 3 , 4 ) // Inferred type : Array < Int >

1 val a r r a y 2 : Array<Long> = a r r a y O f ( 1 , 2 , 3 , 4 )

2

3 // Creates an Array < String > with values ["0" , "3" , "6" , "9" , "12" , "15"]

4 { −> ∗ }

val a r r a y 3 = Array ( 6 , i ( i 3 ) . t o S t r i n g ( ) )

5 Listato 13: Alcuni esempi di creazione di vettori in Kotlin

Stringhe e string templates

Il comportamento delle stringhe in Kotlin è simile a quello visibile in Java, con

alcuni miglioramenti.

Le stringhe in Kotlin si indicano con il tipo di dato e sono, come in

String

Java, immutabili.

É possibile accedere agli elementi delle stringhe tramite l’indexing operator

(per esempio nello stesso modo in cui si accede agli elementi di un vet-

str[i]),

tore, oppure tramite l’iterazione all’interno di un ciclo. La concatenazione di più

stringhe avviene come in Java tramite l’operatore e funziona anche quando è

+

necessario concatenare stringhe e altri tipi di valori.

Nonostante sia presente l’operatore di concatenazione, è spesso preferibile uti-

lizzare i cosiddetti string templates: è possibile posizionare una variabile all’inter-

no di una stringa tramite l’uso del carattere che funge da segnaposto. Durante

$

l’interpolazione, i segnaposto vengono rimpiazzati con i rispettivi valori. Questo

meccanismo rende il codice più ordinato, evitando di dividere la stringa in porzioni

ogniqualvolta occorra inserire il valore di una variabile o di un’espressione.

Nel listato 14 vengono mostrati alcuni esempi:

val s t r = " Hello "

1 val c = s t r [ 1 ] // Inferred type : Char

2 17

18 {

f o r ( i in s t r )

3 // ...

4 }

5

6 val s t r 2 = + 1 + + 2

" alfa " " beta " // str2 = " alfa1beta2 "

7

8 val i = 30

9 p r i n t l n ( )

" i = $i " // Prints " i = 30"

10

11 val s t r 3 = " abcde "

12 p r i n t l n ( )

" $str3 . length is $ { str3 . length } " // Prints " abcde . length is 5"

13 Listato 14: Alcuni esempi di utilizzo delle stringhe e string

templates in Kotlin

3.4 Inferenza di tipo

Come già accennato negli esempi precedenti, in Kotlin quando la dichiarazione e

l’inizializzazione di una variabile avvengono sulla stessa linea di codice, è possibile

omettere l’indicazione del tipo della variabile. Questo meccanismo, non presente

in questi termini in Java, viene chiamato inferenza di tipo: il compilatore inferisce

automaticamente il tipo dal contesto, perciò non è necessario che il programmatore

lo specifichi esplicitamente.

È possibile osservare inferenza in molteplici esempi precedentemente mostrati:

a linee 1 e 2 del listato 4, a linea 8 del listato 5, a linee 1 e 4 del listato 9 ed infine

a linea 1 del listato 10.

Se tuttavia si volesse assegnare un valore intero ad una variabile contenente

una stringa, bisognerebbe specificare un tipo in comune tra e in

String Int:

questo caso si dovrebbe optare per (esempio nel listato 15).

Any

var name : Any = " Sara "

1 name = 15 // Allowed

2 Listato 15: Utilizzo del tipo Any

è l’equivalente del tipo di Java, rappresenta la radice della gerarchia

Any Object

dei tipi di Kotlin, di conseguenza tutte le classi ereditano da esso (pertanto anche

le classi e

String Int). 18 19

Come si può notare dal prossimo listato 16, l’inferenza di tipo non si limita

soltanto ai tipi di dato di base, ma funziona egregiamente anche con funzioni e

tipi composti quali coppie di valori e mappe:

{

fun sum ( a : Int , b : Int ) : Int

1 return a + b

2 }

3

4 // Inferred type : Int

5 val t o t a l = sum ( 3 0 , 4 0 )

6

7 // Inferred type : Pair < Int , String >

8 val p a i r = t o t a l t o " Seventy "

9

10 // Inferred type : Pair < Pair < Int , String > , Float >

11 val m u l t i P a i r = t o t a l t o t o 7 0 . 0 f

" Seventy "

12

13 // Inferred type : Map < Int , String >

14 val map = mapOf ( t o t a l t o , 90 t o )

" Seventy " " Ninety "

15

16 // Inferred type : Map < Int , Any >

17 val superMap = mapOf ( t o t a l t o , 90 t o 9 0 . 0 f )

" Seventy "

18 Listato 16: Applicazioni d’inferenza di tipo in Kotlin

3.5 Strict null safety

Come probabilmente è stato sperimentato nel tempo da molti programmatori Java,

una delle sorgenti d’errore più diffuse è il non corretto controllo dei valori nulli,

con conseguente lancio dell’insidiosa NullPointerException.

Per evitare questo genere di problemi alcuni linguaggi moderni, compreso Ko-

tlin, possiedono un meccanismo di sicurezza dalla nullabilità inserito direttamente

all’interno del proprio type system. In questo modo è possibile scrivere codice

molto più sicuro e convertire gli errori a tempo di esecuzione in errori a tempo di

compilazione; un vantaggio non da poco. Il meccanismo viene chiamato strict null

safety (o più semplicemente null safety) e funziona poiché il type system di Kotlin

distingue tra i riferimenti che possono contenere valori nulli (nullable references)

e quelli che invece non possono (non-nullable references). Di default i tipi non

possono contenere valori nulli e ciò viene reso possibile solamente se esplicitamen-

19

20

te indicato dal programmatore. Un esempio è quello mostrato da riga 1 a 6 del

precedente listato 5.

Operatore di chiamata sicura

L’operatore di chiamata sicura (safe call operator ) si indica con i caratteri e si

?.

comporta nel seguente modo: prima di tutto compie in automatico un controllo

sulla nullabilità della parte a sinistra dell’operatore, se l’esito risulta essere positivo

allora restituisce altrimenti (valore non nullo) esegue e restituisce il risultato

null,

dell’espressione sulla parte destra.

La sintassi di questo operatore è la seguente:

object?.method

Nei seguenti listati 17 e 18 vengono mostrati due esempi a confronto (il primo in

codice Java, il secondo in Kotlin) su Android:

@Override JAVA

1 {

public v o i d o n C r e a t e ( Bundle s a v e d I n s t a n c e S t a t e )

2 super . o n C r e a t e ( s a v e d I n s t a n c e S t a t e ) ;

3 // Correct compilation but possible error at runtime !

4 f i n a l b o o l e a n i s S w i t c h e d O n = s a v e d I n s t a n c e S t a t e . g e t B o o l e a n ( ) ;

" switch "

5 }

6 Listato 17: Possibile errore a tempo di esecuzione in Java

Sebbene il codice Java compili correttamente, la chiamata al metodo getBoolean

sull’oggetto può provocare un errore a tempo di esecuzione,

savedInstanceState

determinando il lancio di una Questo accade a causa

NullPointerException.

della dimenticanza dei controlli sulla nullabilità dell’oggetto savedInstanceState.

{

override fun o n C r e a t e ( s a v e d I n s t a n c e S t a t e : Bundle ? ) KOTLIN

1 super . o n C r e a t e ( s a v e d I n s t a n c e S t a t e )

2 val i s S w i t c h e d O n : Boolean? = s a v e d I n s t a n c e S t a t e ? . g e t B o o l e a n ( )

" switch "

3 }

4 Listato 18: Operatore di chiamata sicura in Kotlin

20 21

Nell’esempio in Kotlin, invece, questo problema viene risolto utilizzando l’opera-

tore di chiamata sicura: se è nullo, allora viene restituito

savedInstanceState

altrimenti viene chiamato il metodo e restituito il risultato.

null, getBoolean

Da tenere a mente tuttavia che i riferimenti potenzialmente nulli possono re-

stituire un valore nullo, perciò è necessario (il compilatore Kotlin lo impone) che il

risultato dell’espressione sia di tipo (specificato esplicitamente o inferito

Boolean?

automaticamente), come indicato nell’esempio.

Questo operatore è utile anche durante le chiamate a catena. Se per esempio

Bob, un dipendente, può essere assegnato a un dipartimento (oppure no), il quale

a sua volta può possedere un altro dipendente come capo dipartimento, allora per

ottenere il nome del capo dipartimento di Bob (se presente), è possibile scrivere

13

quanto segue nel listato 19:

val name = bob ? . department ? . head ? . name

1 Listato 19: Operatore di chiamata sicura utilizzato in una catena

di chiamate

La precedente espressione restituisce quindi soltanto se rileva che un oggetto

null

è nullo; in questo modo si risparmia di controllare con molteplici la nullabilità

if

o meno di ogni oggetto.

Operatore elvis

L’operatore elvis (Elvis operator ) viene rappresentato per mezzo dei due caratteri

e si comporta nella maniera seguente: se l’operando di sinistra non è nullo,

?:

allora l’operatore di elvis lo restituisce come risultato, altrimenti restituisce il

secondo operando.

La sintassi di questo operatore è:

first operand ?: second operand

Nel listato 20 ne viene mostrato un esempio pratico:

13 Per maggiori informazioni visitare: http://archive.is/KtvGp

21

22 {

override fun o n C r e a t e ( s a v e d I n s t a n c e S t a t e : Bundle ? )

1 super . o n C r e a t e ( s a v e d I n s t a n c e S t a t e )

2 val i s S w i t c h e d O n : Boolean = s a v e d I n s t a n c e S t a t e ? . g e t B o o l e a n ( ) ? : f a l s e

" switch "

3 }

4 Listato 20: Operatore elvis in Kotlin

L’operatore elvis nell’esempio restituisce il valore dell’espressione savedInstanceSta-

se non è nullo, altrimenti re-

te?.getBoolean("switch") savedInstanceState

stituisce Questo operatore permette quindi di specificare un valore di

false.

default da restituire solo nel caso l’operando di sinistra non produca un risultato

idoneo (cioè non nullo).

Risulta inoltre importante sottolineare il fatto che in questo caso la variabile

è di tipo non è infatti più necessario specificarla come

isSwitchedOn Boolean:

in quanto l’operatore di elvis impedirà sempre che possa essere

Boolean?, null.

Questo operatore può essere utilizzato ovviamente anche congiuntamente a

catene di chiamate, ne è un buon esempio il listato 21:

val name = bob ? . department ? . head ? . name ? : " Jack "

1 Listato 21: Operatore elvis utilizzato insieme a una catena di chiamate

Operatore di asserzione non nulla

L’operatore di asserzione non nulla (not-null assertion operator ) viene indicato

con i tre caratteri e compie implicitamente un cast di una variabile potenzial-

!!.

mente nulla ad una non nulla. Il suo utilizzo è però fortemente sconsigliato, poiché

può essere fonte di errori a runtime e portare ad una NullPointerException.

Se il progra

Dettagli
Publisher
A.A. 2018-2019
42 pagine
1 download
SSD Scienze matematiche e informatiche INF/01 Informatica

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher Nikwanted di informazioni apprese con la frequenza delle lezioni di Programmazione e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli Studi di Bologna o del prof Viroli Mirko.