Storia e riferimenti
Kotlin è già in circolazione da un po', infatti è stato annunciato nel 2011 e la sua prima anteprima è uscita nel 2012. Kotlin 1.0 è stato rilasciato nel 2016, e a quel punto JetBrains si è impegnata a mantenere la compatibilità con le versioni precedenti per le caratteristiche stabili a partire da 1.0.
Puoi trovare ottimi materiali di formazione e riferimenti su https://kotlinlang.org/. Il team di Android ha trovato il tutorial Kotlin Koans particolarmente utile perché spiega come iniziare facilmente a scrivere alcuni snippet in Kotlin. Questi tutorial vanno da argomenti semplici a molto complessi, progredendo dalle basi agli idiomi più sofisticati di Kotlin.
Perché Kotlin?
Perché il team di Android ha deciso di supportare Kotlin? Principalmente perché pensa che sia un ottimo linguaggio che renderà la scrittura di app Android più facile e divertente.
È perfetto per l'ecosistema Android esistente ed è compatibile al 100% con il linguaggio di programmazione Java. Puoi aggiungere quanto Kotlin desideri alla tua codebase esistente e combinare liberamente i due linguaggi all'interno dello stesso progetto. Richiamare il codice di Kotlin dal codice scritto nel linguaggio di programmazione Java funziona (Just Works™). Anche la direzione opposta di solito funziona senza alcun impegno da parte dello sviluppatore, applicando automaticamente alcune convenzioni di traduzione (ad esempio, le proprietà Get e Set vengono create per te). Con l'aiuto di alcune annotazioni di Kotlin, puoi personalizzare anche la modalità di esecuzione della traduzione.
Infine, moltissimi sviluppatori ci hanno detto che amano il linguaggio Kotlin (inclusi parecchi sviluppatori del team Android). Esiste già una community entusiasta di sviluppatori Kotlin per Android, e il team di Android è stato regolarmente punzecchiato con domande su Kotlin in occasione di eventi pubblici. La community Android ha parlato e noi abbiamo ascoltato.
Un breve tour
Per capire da dove provenga tutto l'entusiasmo nei confronti di Kotlin, ecco un tour breve, ma lontano dall'essere completo, di alcuni degli aspetti particolarmente interessanti di Kotlin.
Nullable
Il compilatore Kotlin impone che le variabili in grado di contenere valori null siano dichiarate in modo esplicito, quindi niente più NullPointerExceptions al runtime!
var neverNull: String = "something"
var mightBeNull: String? = null // "?" indicates this can be null
if (neverNull.length > 0) { // This is OK
…
}
if (mightBeNull.length > 0) { // Compiler catches this error for you
…
}
Confronta questo con uno scenario simile che utilizza parametri denominati e argomenti predefiniti:
fun orderPizza(size: Size, pepperoni: Boolean, mushrooms: Boolean,
ham: Boolean, pineapple: Boolean, pickles: Boolean,
sausage: Boolean, peppers: Boolean, onion: Boolean)
{
...
}
// Wait… did I just order pickles on my pizza?
// Why do we even have that option?
orderPizza(Size.LARGE, true, false, false, false, true,
false, true, false)
Oltre a evitarti di produrre delle pizze immangiabili, è molto più facile da leggere. Riduce anche il numero di varianti di funzioni sovraccaricate che dovrai scrivere.
Istruzione When
Kotlin include la variazione di un'istruzione switch che permette la corrispondenza con espressioni arbitrarie.
// Please don't put this in your app!
when {
password.equals("password") -> println("Insecure password!")
password.length < 4 -> println("Too short!")
else -> {
println("Secure password!")
}
}
Smart Cast
Perché dovresti assegnare qualcosa a una classe dopo aver appena provato che è un'istanza di quella classe? Con Kotlin, non devi più farlo.
if (obj is String) {
// Compiler casts obj to a String for you.
// (Would work with && instead of nested ifs too.)
if (obj.length > 0) {
…
}
}
Ciò generalizza anche l'istruzione When:
// Assume reasonable implementations of Cat and Dog
when (obj) {
is Cat -> obj.meow(...)
is Dog -> obj.woof(...)
else -> {
…
}
}
Funzioni di estensione
Sostanzialmente, Kotlin ti consente di applicare nuovi metodi di retcon in una tipologia esistente. Se, come molte persone, ti piacerebbe che la classe String avesse un metodo toPigLatin
, adesso puoi aggiungerlo senza dover creare una nuova classe di helper per eseguire il wrapping di String o dover soddisfare un comitato linguistico:
// The "String." prefix indicates that this method should
// extend the existing String class
fun String.toPigLatin() : String {
...
}
val plainOldString : String = "some text"
// Can now call toPigLatin as if were a method on String
println(plainOldString.toPigLatin())
// Or:
println("some text".toPigLatin())
Dichiarazioni di destrutturazione
Abbiamo già visto quanto sia facile definire una semplice classe di dati:
data class Order(val itemCode: String, val quantity: Int,
val price: Float)
La funzione che utilizza una di queste classi come tipo restituito è molto vicina a supportare più valori restituiti:
fun getOrder(...): Order {
...
return Order(itemCode, quantity, price);
}
Per arrivare a questo punto, puoi utilizzare la sintassi della dichiarazione di destrutturazione. L'istruzione seguente prende l'oggetto Order
, estrae le tre proprietà e le assegna alle tre variabili what
, howMany
e howMuch
, tutto grazie al compilatore Kotlin, che deduce anche i tipi giusti per te.
val (what, howMany, howMuch) = getOrder(...)
Lambda
Kotlin ha una sintassi estremamente concisa per i lambda, che semplifica l'espressione di potenti paradigmi di programmazione funzionale. Ecco un semplice esempio che utilizza un lambda per verificare che tutto il contenuto di una collection sia una stringa:
fun allStrings(collection: Collection)=
collection.all { it is String }
La sintassi dei lambda è il blocco predefinito di una delle caratteristiche più belle di Kotlin: la capacità di creare generatori che utilizzano una sintassi simile a JSON, che a sua volta è anche sintatticamente valida in Kotlin. L'esempio seguente è stato estrapolato da una discussione più ampia, ma dà comunque l'idea di ciò che si può fare utilizzando questo snippet:
fun generatePage(withEmphasis : Boolean) {
val result =
html {
head {
title { +"Kotlin Builders" }
}
body {
h1 { +"Kotlin Builders" }
p {
+"This is "
if (withEmphasis) b { +"really " }
+"interesting"
a(href = "https://goo.gl/rHwJio") { +"More here" }
}
}
}
println(result)
}
Possiamo notare un paio di cose interessanti qui. Innanzitutto, dimostra come possa essere espressiva la sintassi funzionale di Kotlin: in questo esempio, "html
", "head
", "body
ecc. sono solo funzioni scritte in Kotlin e i contenuti delle parentesi graffe che seguono sono i parametri funzionali (questo snippet utilizza funzioni con nomi che corrispondono ai tag HTML per creare la rappresentazione di una pagina web, ma ovviamente puoi utilizzare questo modello per creare qualsiasi struttura di dati complessa con i nomi che desideri). La seconda cosa interessante è la condizionale "withEmphasis
". Potrebbe sembrare che stiamo mettendo insieme codice (if (withEmphasis)
…) e dati (tutti tag HTML-eschi), ma in questo caso i "dati" non sono altro che codice. Poiché in fondo si tratta solo di codice, questo ti consente di creare strutture di dati complesse utilizzando una sintassi dichiarativa, ma anche di avere accesso inline alle funzionalità complete del linguaggio Kotlin.
Come iniziare
Se non vedi l'ora di utilizzare Kotlin, inizia subito con il codice online qui. Basta premere il triangolo verde per compilare ed eseguire.
Per provare Kotlin sulla tua app, segui questi passaggi:
- Scarica Android Studio 3.0
- Apri i tuoi file ".java" esistenti
- Richiama "Code > Convert Java File to Kotlin File"
L'IDE ti mostrerà come aggiungere le dipendenze di Kotlin al tuo progetto per poi convertire il codice in codice Kotlin funzionalmente equivalente (l'IDE ti offrirà inoltre di ritoccare tutti i siti di chiamata in base alla classe convertita, quando opportuno, per essere più idiomaticamente simili a Kotlin, ad esempio quando i metodi statici vengono spostati negli oggetti complementari).
Potrai trovare molte altre informazioni relative a come iniziare a usare Kotlin su developer.android.com.