Overview
- Équivalent de bibliotèques Java:
MockK
: Mocking
KtLint
: Linter
Koin
: injection de dépendances.
Variables
Méthodes
- On définit une méthode comme suit:
fun <name>(param : Type, param: Type = <défaut>) : Type {
}
- Le type de retour par défaut est
Unit
- On peut utiliser les paramètres nommées.
- On peut définir des paramètres par défaut.
- On peut faire des méthodes expression et des méthodes infix:
// Expression
fun plusOne(param : Int) : Int = param + 1
// Infix
infix fun plusOne(param : Int) : Int = param + 1
- On peut étendre des classes avec des nouvelles méthodes :
fun <Class>.method() : String {
return "$This?"
}
inline
copie le corps de la méthode où il est appelé. Bien pour les getters, les setters et les petites lambdas.
- On peut overloader les opérateurs
+
, -
, *
et /
avec:
operator fun plus(param : Type) : Type {
val newValue = param.value + 1
return new Type(newValue)
}
- Utilisation des lambdas :
val x : (t : Type) -> AutreType = { variables -> corps}
- On peut faire une lambda sans variable avec
{ corps }
Classe
- Constructeur par défaut vide ou complet en fonction des paramètres.
- Possible d'ajouter des constructeurs avec :
class Truc(truc : Type) {
constructor(param : Int, param2 : Int) : this(Type(param + parm2))
}
class Truc(var truc : Type) {
// truc est un class field ici.
}
- Par défaut, classes et membres
final
. Il faut ajouter open
pour permettre l'héritage et open
sur les méthodes pour permettre l'héritage :
open class C {
open val myValue = 1
}
class D : C() {
override val myValue = 0
}
- On peut utiliser
init { }
comme bloc constructeur.
- On peut faire un bloc
static
en ajoutant soit la valeur au top level, soit un object / companion object { }
.
- Le nesting est autorisé.
data class
est un équivalent des records.
- Les enumérations sont déclarées avec le mot clef
enum class {}
object
permet de faire des singletons.
Flot de contrôle
For
for (i in start..end)
for(i in start until end)
for (i in start until end step inc)
for (content in data)
data.forEach()
If
- Fonctionne pour checker
null
, mais sur les val
uniquement.
if'(truc) corps else corpsElse
est une expression.
When
- Remplace le mot clef
switch
.
- Permet de faire du pattern matching :
when(i) {
is Int -> truc
is String -> truc
else -> default case ou {}
}
when(i) {
0 -> truc
1 -> autre truc
in start..end -> truc
else -> default case
}
``
- Il s'agit d'expression également donc on peut l'assigner.
Scope functions
data.let { }
permet d'accès à l'objet via le mot clef it
. Renvoie le resultat de la lambda.
with(data) { }
fait la même chose que let
mais référence l'objet avec this
et n'est pas une méthode sur un objet. Renvoie le resultat de la lambda.
data.run { }
fonctionne pareil que let
mais en important l'object comme this
et non comme une variable. Renvoie le resultat de la lambda.
data.apply {}
prend l'objet et fait la même chose que run
avec this
. Il renvoie l'objet lui même cependant.
Interfaces
- Permet de définir des valeurs par défaut et getters et setters.
interface Truc {
var test : Int get() = 1
}
class Bidule : Truc, Truc2 {
// corps
}
Abstract class
Génériques
- On peut déclarer des génériques de la même manière que Java
class Truc<T> {
// Corps
}
- Kotlin fournit
in
et out
pour spécifier les types d'entrée et de sortie :
out T
ne peut qu'être utilisé en sortie.
interface Produce<out T> {
fun produce() : T
}
in T
ne peut être utilisé qu'en entrée :
interface Consume<in T> {
fun consume(t :T)
}
- On peut passer des contraintes comme Java avec
<T : Type>
- Si on ne connait pas le type que l'on doit créer, on peut passer
*
.
- On peut utilise
reified
avec les méthodes inline
pour vérifier le type de retour :
inline fun <reified T> method(p : Any) {
return p as T
}
Type alias
- Ajoute du sucre syntaxique pour les types avec
typealias Truc = Int
Modifiers
- Par défaut ce qui est à top level est
public
.
- On peut ajouter le mot clefs
private
pour rendre privé à la classe. Attention ce n'est pas accessible depuis les classes mères.
internal
est privé au module.
protected
authorise aux sous classes aussi.
Coroutines
- Threads légères. Une coroutine est coopérative à la différence d'une thread.
- On peut récupérer le resultat avec
Class.async
.
- On peut utiliser
await()
pour avoir le resultat et cancel()
pour stopper.