15 Juillet 2025 - Gestion des données manquantes avec les Optionals Swift
Jour 37 de formation et 14ème jour des 100 Days of SwiftUI ! Aujourd’hui, nous entrons dans l’un des concepts les plus importants et parfois déroutants de Swift : les Optionals. Paul Hudson le dit lui-même : “Optionals and Closures are the most important and difficult to understand in Swift”.
#
Comprendre les Optionals : la boîte de Schrödinger du code
Les Optionals en Swift, c’est comme une boîte : quelque chose peut être dedans, ou pas. Cette métaphore m’aide vraiment à visualiser le concept. Contrairement à d’autres langages où une variable peut parfois contenir quelque chose de inattendu, Swift nous force à être explicites sur ce qui peut être absent.
##
Pourquoi les Optionals existent-ils ?
Imaginons qu’on cherche l’opposé de “Peach” dans notre dictionnaire de personnages Mario :
let opposites = ["Mario": "Wario", "Luigi": "Waluigi"]
let peachOpposite = opposites["Peach"] // Que se passe-t-il ?
Swift ne peut pas deviner ce qu’on veut faire si “Peach” n’existe pas. Plutôt que de planter ou de retourner une valeur par défaut arbitraire, il retourne un Optional - une boîte qui peut contenir une valeur ou être vide.
#
Les différentes façons de “déballer” un Optional
##
1. If Let : la méthode sécurisée
La technique if let permet de vérifier s’il y a quelque chose dans la boîte avant de l’utiliser :
if let peachOpposite = opposites["Peach"] {
print(peachOpposite)
} else {
print("Nothing in Array")
}
Ce qui me plaît avec cette approche, c’est qu’elle crée une version temporaire et non-optionnelle de notre variable uniquement dans le scope du if
. Pas de risque d’erreur !
##
2. Guard : sortir tôt en cas de problème
Les guards inversent la logique - ils s’occupent du cas d’erreur en premier :
func printSquare(of number: Int?) {
guard let number = number else {
print("Missing Input")
return
}
print("\(number) x \(number) is \(number * number)")
}
Cette approche me semble plus naturelle pour les fonctions : on traite d’abord les cas problématiques, puis on se concentre sur la logique principale.
##
3. Nil Coalescing : fournir une valeur par défaut
L’opérateur ?? (nil coalescing) est génial quand on veut simplement une valeur de secours :
let favorite = tvShow.randomElement() ?? "None"
let userInput = Int(input) ?? 0
C’est ma technique préférée quand je veux que l’application continue à fonctionner même si une donnée manque.
#
Optional Chaining : enchaîner les “peut-être”
L’Optional Chaining permet d’enchaîner plusieurs opérations qui pourraient échouer :
let chosen = names.randomElement()?.uppercased() ?? "No One"
Si randomElement()
retourne nil
, toute la chaîne s’arrête et retourne nil
. Sinon, on continue avec uppercased()
. C’est élégant et sûr !
#
Try? : quand les erreurs deviennent des Optionals
Avec try?, on peut transformer une fonction qui lance des erreurs en Optional :
if let user = try? getUser(id: 23) {
print("User: \(user)")
}
Cette approche est parfaite quand le détail de l’erreur ne nous intéresse pas - on veut juste savoir si ça a marché ou pas.
#
Exercices pratiques réalisés
##
Challenge du jour : fonction en une ligne
Le défi était d’écrire une fonction qui accepte un array optionnel d’entiers et retourne un élément aléatoire, ou un nombre entre 1 et 100 si l’array est vide ou nil
:
let arrayOneLine = { (array: [Int]?) -> Int in
array?.randomElement() ?? Int.random(in: 1...100)
}
Voir cette solution fonctionner m’a donné l’impression de résoudre un puzzle - combiner optional chaining et nil coalescing en une ligne élégante.
##
Exercices d’approfondissement
J’ai ensuite travaillé sur plusieurs exercices pour maîtriser les différentes techniques :
- Comptage de caractères sécurisé : gérer les chaînes
nil
- Extraction du premier élément : avec optional chaining
- Calculs avec valeurs par défaut : utiliser nil coalescing pour les opérations
- Calcul de moyenne robuste : combiner guard et vérifications
- Conversion conditionnelle : transformer des mots en nombres avec gestion d’erreur
##
Leçon apprise avec les Guards
Une découverte importante : on peut combiner plusieurs conditions dans un guard avec des virgules :
guard let number = number, let convertedNumber = convertDict[number] else {
return -1
}
Cette syntaxe est plus propre que d’imbriquer plusieurs guards.
À demain pour le dernier jour théorique des 100 Days of SwiftUI !