Kotlin Language

Hello, World

Eccoci al solito saluto introduttivo:

  Esempio 2.1
1
2
3
4
fun main(args : Array<String>)
{
  println("Hello, world!")
}

La riga 1 ci presenta la keyword fun che è quella utilizzata dal linguaggio per presentare le funzioni. Notiamo subito che le funzioni sono top level, ovvero possono essere dichiarate al livello più alto non solo all'interno di una classe. Subito dopo troviamo la lista dei parametri, in particolare abbiamo un parametro di nome args che è un array di stringhe.
La riga 2 ci mostra il primo simbolo di una coppia di graffe che, come in tanti altri linguaggi, costituiscono i delimitatori delle "frasi" del linguaggio. La frase in questo programma si chiuse alla riga 4.
La riga 3 costituisce il corpo del programma. Da notare l'istruzione println, un wrapper per System.Out.println. Kotlin è molto prodigo di queste facilitazioni.
Noterete che non c'è il classico punto e virgola che chiude le istruzioni in tanti linguaggi. In Kotlin, non è quasi mai necessario. Rircordatevi che Kotlin è case-sensitive, ovvero fa distinzione tra maiuscole e minuscole.
E' il momento per un esempio più interattivo:

  Esempio 2.2
1
2
3
4
5
6
fun main(args : Array<String>)
{
  print("Inserisci il tuo nome: ")
  var s1 = readLine()
  println("Ciao, ${s1}")
}

La riga 3 vede l'istruzione print, che diversamente da println non va a capo dopo aver esposto il proprio output. ma il punto interessante si ha alla
riga 4 nella quale incontriamo la keyword var; questa introduce una variabile, nell'esempio il nome della variabile stessa è s1. Il segno = è l'operatore di assegnamento in questo linguaggio, come in molti altri. Ancora più interessante notare che alla variabile non è attribuito un tipo esplicitamente; esso sarà desunto dal valore ad esso assegnato, in questo esempio readLine() legge una stringa e questo sarà appunto il tipo di s1. Kotlin supporta pertanto l'inferenza di tipo, cioè la possibilità di assegnare un tipo ad una variabile sulla base dei suoi possibili valori. In Java, il fratello maggiore di Kotlin, la dichiarazione di una variabile inizia col tipo. In questo linguaggio si è scelto un approccio diverso, proprio perchè è possibile omettere il tipo stesso. Tuttavia, Se volete specificare un tipo per una variabile in via esplicita senza lasciar fare all'inferenza, potete usare questa sintassi:

var nomevariabile : tipo = valore iniziale

Il valore iniziale può essere omesso ma comunque andrà assegnato prima dell'uso, come ribadiremo anche più avanti. Può anche essere un'espressione più complessa di un semplice numero o di una stringa.
Anche la riga 5 presenta qualche motivo di interesse in quanto si può vedere in la possibilità di usare l'interpolazione nelle stringhe. Il valore della variabile è quindi usato inserendolo direttamente nella stringa da presentare come output, senza bisogno di ricorrere a concatenazioni o altri artifici, il che rende il codice un po' più compatto. Il sistema è semplice, basta usare il simbolo del dollaro seguito dalla variabile che si intende interpolare messa tra parentesi tonde.
Abbiamo introdotto le variabili attaverso var ma esiste un'altra keyword che viene usata per questo scopo ovvero val. A differenza di quanto accade in presenza di var, una variabile introdotta tramite val è immutabile, cioè il suo valore, una volta fissato, non può essere cambiato. In pratica una cosa del tutto simile al readonly di C# o final di Java, per fare due esempi. Quindi se scriviamo:

var x = 7
val y = 8
x = 9
y = 0


l'ultima riga dà origine ad un errore:

Kotlin: Val cannot be reassigned

che mi sembra abbastanza esplicito, come messaggio. Il comportamente di Kotlin in questo è identico a quello che si riscontra in Scala. Le linee guida suggerirebbero di dichiarare, per quanto possibile, le variabili (a questo punto un po' contraddittorio chiamarle così) tramite la keyword val e limitare solo a quando davvero necessario l'uso di var. Questo tra l'altro rende più semplice l'eventuale uso di un approccio di tipo funzionale.
Del tutto analogamente non è possibile modificare il tipo di una variabile, sia esso assegnato esplicitamente, sia esso ottenuto per inferenza:

var x : Int = 0
x = "ciao"


Questo non si può fare, il compilatore si esprimerà chiaramente e, se usate IntelliJ, anche l'IDE stesso vi manderà un segnale. 

La funzione main è predisposta per accettare parametri a riga di comando, parametri che vengono raccolti da quella variabile di nome args, un array di stringhe, che trovate nella riga 1 dei programmi fin qui presentati e anche nel prossimo:

  Esempio 2.3
1
2
3
4
5
6
7
8
9
fun main(args : Array<String>)
{
  if (args.size() == 0)
  {
    println("Inserisci il tuo nome")
    return
  }
  println("Hello, ${args[0]}!")
}

Anche qui vediamo all'opera l'interpolazione di una variabile all'interno di una stringa.

Le variabili, siano esse introdotte tramite var o tramite val, vanno sempre inizializzate, ovvero va loro assegnato un valore iniziale altrimenti non potrete usarle. Scrivere:

val x : Int
println(x)


origina un esplicito errore a runtime, e questo dimostra che non c'è una inizializzazione di default.

Un ultimo cenno, per concludere questo paragrafo, lo dedichiamo ai commenti, anche se non c'è molto da dire:
// introduce un commento su linea singola
/* ne introduce uno su più righe che dovrà essere chiuso da */