Open Source Your Knowledge, Become a Contributor
Technology knowledge has to be shared and made accessible for free. Join the movement.
Les bases de Kotlin
la syntaxe
La syntaxe est très inspirée de Java, avec toutefois quelques particularités dont certaines seront vues ultérieurement
- fichiers
.kt
- pas de
;
- déclaration de variables avec
val
/var
- typage postfixé
- déclaration des fonctions avec
fun
- les fonctions sont des entités de première classe, au même titre que les classes
- pas de
new
pour appeler un constructeur - les expressions de contrôle varient un peu
- contrôle natif des types nullables
- wildcards de généricité (
extends
ousuper
en Java) avecin
etout
- inférence de type
- …
variables et typage
On déclare un variable avec var
.
Kotlin fait de l'inférence de type, c'est-à-dire qu'il sait déduire le type. Mais une fois défini, le type reste figé !
Le mot clé val
permet de déclarer une constante (mot clé final
de Java).
Tout est objet, même les types primitifs (pas boxing / unboxing) : Boolean
,Byte
,Int
, Long
, String
, Float
, Double
, Unit
Le type tableau s'écrit Array<T>
avec T
le type des éléments du tableau.
Le type Unit
peut-être assimilé au type Void
de java. Un fonction retourne Unit
par défaut !
Pour des raison de cohérence dans l'aspect fonctionnel du language (toute fonction retourne quelque chose),
une fonction qui ne retourne rien en théorie, retourne l'object Unit
. Unit
ne peut prendre en effet qu'une valeur unique, en comparaison Boolean
en prend 2 :
true
et false
.
Le type Any
correspond à n'importe quel type, similaire au type Objet
de java.
Les variables et fonctions peuvent être nommées de manière plus flexible grâce à ````. Utile pour nommer les tests unitaires,
ou contourner les conflits de nommage (mockito.``when``(...)
)
Cast et Smartcast
Nous pouvons forcer le type d'une valeur avec l'opérateur as
(unsafe cast operator) ou l'opérateur as?
(safe cast operator).
is
permet de tester le type d'une variable (cf. instanceof
de Java). Intervient alors le SmartCast dans un bloc if
ou when
par exemple !
Égalité
L'opérateur ==
(double-égale) prend le sens du .equals()
de Java.
L'opérateur ===
(triple-égale) prend le sens du ==
de Java, donc égalité sur la référence.
Les chaînes de caractères
Les chaines Multiligne peuvent être écrites sur plusieurs lignes.
Exemple:
Null safety
Kotlin sécurise l'exécution du code avec des types nullable, obligeant le développeur à prendre en compte les cas de nullité.
Exemple :
var nullable: String? = null
var nonNullable: String = ""
var nonNullable: String = null // erreur de compilation
Les types non-nullable, par définition, ne pourront pas être null, finis les if(item == null){…}
!
Pour les types nullable, un arsenal d'opérateurs permettent de ne pas casser le flux de lecture du code.
?.
safe call : accès à une propriété / méthode si l'objet n'est pas null, retourne null sinon?:
operateur elvis : retourner une valeur par défaut si null!!
forcer le cast vers un type non-null.NullPointerException
si l'objet est effectivement null !
Sous le capot, les types nullables ne sont pas wrappés avec des classes Optional
, mais annotés par @Nullable
et @NotNull
,
ce qui améliore les performances.
les structures de contrôle
if
Même si le if
Kotlin est très similaire au if
java, il peut être utilisé en opérateur ternaire car il peut retourner une valeur.
for
L'instruction for
itère sur tous les types d'objets itérables. Par exemple sur des ranges :
when
L'instruction when
est un super switch Java, supportant des conditions complexes.
Exceptions
Toutes les exceptions en kotlin sont unchecked (cf. RuntimeException
), c'est à dire qu'il n'est pas nécessaire d'encadrer systématiquement par des try
/catch
/Finally
les méthodes qui emettent des exceptions.
Comme souvent en Kotlin, try
peut retourner une valeur :
Le type Nothing
est le type particulier d'une fonction qui ne retournera jamais rien, une fonction qui part en échec systématiquement.
fun fail(): Nothing {
throw Exception("Failure")
}
Cependant, pour l'interoperabilité avec Java, nous pouvons indiquer que notre fonction envoi une exception avec l'annotation @Throws
. Le code Java
appelant devra alors l'inclure dans un try
/catch
.
@Throws(NumberFormatException::class)
fun parse(str:String): Int = str.toInt()
Fonctions
Les fonctions et méthodes sont déclarées sous la forme fun name(arg1:T, arg2:U):V { ... }
.
On peut spécifier des paramètres par défaut très simplement, par exemple fun getWeather(date:LocalDate=LocalDate.now()){}
.
Cette fonction pourra être appelée avec getWeather()
À l'appel d'une fonction, les paramètres peuvent être nommés, sans se soucier de l'ordre de déclaration et améliorant la lisibilité.
fun doSomething(one:String, two:Int, three: Int = 0) {
println("one=$one, two=$two, three=$three")
}
fun main(args:Array<String>){
doSomething(two=2, one="ONE")
}
Une fonction dont le corps ne possède qu'une seule instruction (ou chaîne d'instructions), peut être écrite en expression body :
fun square(a:String) = a * a
Comme en Java, nous pouvons spécifier des arguments variables avec le mot clé vararg
. Pour passer un tableau ou une collection
à un argument variable, il suffit de le déstructurer avec *
Lambdas
Les lambda expressions sont déclarées sous la forme val name: (T, U) -> V = { arg1, arg2 -> ... }
.
Dans une lambda avec un paramètre unique, celui peut alors être omis et se nomme it
. On n'utilise pas le mot clé return
pour la valeur de retour d'une lambda.
Si le dernier paramètre d'une fonction est une lambda expression, elle peut être sortie de la liste de paramètres de l'appel.
Quizz
Question 1
var a = 3
a = "Hello"
println(a)
Question 2
val value = 42
val regex = """\d\W$value"""
println(regex)
Question 3
var message:String? = "Message"
var length = message?.length
Question 4
fun upper(str:String? = "default") = str.toUpperCase()
Question 5
// Fichier monpackage.MaFonction.kt
fun hello() = println("Hello")
Question 6
val a = "2048"
val b = 2048.toString()
println("${a == b} ${a === b}")
Question 7
val value = "Message"
println(value as? Int)
println(value as Int?)
Exercices
FizzBuzz
Afficher les nombres de 1 à 100, mais afficher Fizz si le nombre est divisible par 3, Buzz s'il est divisible par 5 et FizzBuzz s'il est divisible à la fois par 3 et par 5.