Sécurité contre les valeurs nulles¶
En Kotlin, il est possible d’avoir une valeur null. Pour aider à prévenir les problèmes avec les valeurs null dans
vos programmes, Kotlin a mis en place une sécurité contre les nullités. La sécurité contre les nullités détecte les
problèmes potentiels avec les valeurs null au moment de la compilation, plutôt qu’au moment de l’exécution.
La sécurité contre les nullités est une combinaison de fonctionnalités qui vous permettent de :
- déclarer explicitement quand les valeurs
nullsont autorisées dans votre programme. - vérifier la présence de valeurs
null. - utiliser des appels sécurisés à des propriétés ou des fonctions qui peuvent contenir des valeurs
null. - déclarer des actions à prendre si des valeurs
nullsont détectées.
Types Nullable¶
Kotlin supporte les types Nullable qui permettent la possibilité pour le type déclaré d’avoir des valeurs null. Par
défaut, un type n’est pas autorisé à accepter des valeurs null. Les types Nullable sont déclarés en ajoutant
explicitement ? après la déclaration du type.
Par exemple :
fun main() {
// neverNull a le type String
var neverNull: String = "Ceci ne peut pas être null"
// Lève une erreur de compilation
neverNull = null
// nullable a un type String nullable
var nullable: String? = "Vous pouvez garder un null ici"
// C'est OK
nullable = null
// Par défaut, les valeurs null ne sont pas acceptées
var inferredNonNull = "Le compilateur suppose non-nullable"
// Lève une erreur de compilation
inferredNonNull = null
// notNull n'accepte pas les valeurs null
fun strLength(notNull: String): Int {
return notNull.length
}
println(strLength(neverNull)) // 18
println(strLength(nullable)) // Lève une erreur de compilation
}
Note
length est une propriété de la classe String qui
contient le nombre de caractères dans une chaîne.
Vérifier les valeurs nulles¶
Vous pouvez vérifier la présence de valeurs null dans les expressions conditionnelles. Dans l’exemple suivant, la
fonction describeString() a une instruction if qui vérifie si maybeString n’est pas null et si sa length
est supérieure à zéro :
fun describeString(maybeString: String?): String {
if (maybeString != null && maybeString.length > 0) {
return "Chaîne de longueur ${maybeString.length}"
} else {
return "Chaîne vide ou null"
}
}
fun main() {
val nullString: String? = null
println(describeString(nullString))
// Chaîne vide ou null
}
Utiliser des appels sécurisés¶
Pour accéder en toute sécurité aux propriétés d’un objet qui peut contenir une valeur null, utilisez l’opérateur
d’appel sécurisé ?.. L’opérateur d’appel sécurisé renvoie null si l’objet ou l’une de ses propriétés accédées
est null. Ceci est utile si vous voulez éviter que la présence de valeurs null déclenche des erreurs dans votre
code.
Dans l’exemple suivant, la fonction lengthString() utilise un appel sécurisé pour renvoyer soit la longueur de la
chaîne, soit null :
fun lengthString(maybeString: String?): Int? = maybeString?.length
fun main() {
val nullString: String? = null
println(lengthString(nullString))
// null
}
Note
Les appels sécurisés peuvent être chaînés de manière à ce que si une propriété d’un objet contient une valeur null,
alors null est renvoyé sans qu’une erreur soit levée. Par exemple :
L’opérateur d’appel sécurisé peut également être utilisé pour appeler en toute sécurité une fonction d’extension ou de
membre. Dans ce cas, une vérification de nullité est effectuée avant l’appel de la fonction. Si la vérification détecte
une valeur null, alors l’appel est sauté et null est renvoyé.
Dans l’exemple suivant, nullString est null donc l’invocation
de .uppercase() est sautée et null est
renvoyé :
Utiliser l’opérateur Elvis¶
Vous pouvez fournir une valeur par défaut à retourner si une valeur null est détectée en utilisant
l’opérateur Elvis ?:.
Écrivez sur le côté gauche de l’opérateur Elvis ce qui doit être vérifié pour une valeur null.
Écrivez sur le côté droit de l’opérateur Elvis ce qui doit être renvoyé si une valeur null est détectée.
Dans l’exemple suivant, nullString est null donc l’appel sécurisé pour accéder à la propriété length renvoie une
valeur null.
En conséquence, l’opérateur Elvis renvoie 0 :
Pour plus d’informations sur la sécurité des nullités en Kotlin, voir Null safety.
Pratique¶
Exercice¶
Vous avez la fonction employeeById qui vous donne accès à une base de données d’employés d’une entreprise.
Malheureusement, cette fonction renvoie une valeur du type Employee?, donc le résultat peut être null. Votre but est
d’écrire une fonction qui renvoie le salaire d’un employé quand son id est fourni, ou 0 si l’employé est manquant
dans la base de données.
data class Employee (val name: String, var salary: Int)
fun employeeById(id: Int) = when(id) {
1 -> Employee("Mary", 20)
2 -> null
3 -> Employee("John", 21)
4 -> Employee("Ann", 23)
else -> null
}
fun salaryById(id: Int) = // Écrivez votre code ici
fun main() {
println((1..5).sumOf { id -> salaryById(id) })
}
Réponse
data class Employee (val name: String, var salary: Int)
fun employeeById(id: Int) = when(id) {
1 -> Employee("Mary", 20)
2 -> null
3 -> Employee("John", 21)
4 -> Employee("Ann", 23)
else -> null
}
fun salaryById(id: Int) = employeeById(id)?.salary ?: 0
fun main() {
println((1..5).sumOf { id -> salaryById(id) })
}