Optionnel
Optionnel
struct HarryPotter {
var name: String
var publicationYear: Int
}
let books = [
HarryPotter(name: "Harry Potter à l'école des sorciers", publicationYear: 1997),
HarryPotter(name: "Harry Potter et la Chambre des secrets", publicationYear: 1998),
HarryPotter(name: "Harry Potter et le Prisonnier d'Azkaban", publicationYear: 1999),
HarryPotter(name: "Harry Potter et la Coupe de feu", publicationYear: 2000),
HarryPotter(name: "Harry Potter et l'Ordre du Phénix", publicationYear: 2003),
HarryPotter(name: "Harry Potter et le Prince de sang-mêlé", publicationYear: 2005),
HarryPotter(name: "Harry Potter et les Reliques de la Mort", publicationYear: 2007),
HarryPotter(name: "Harry potter le retour à Poudlard", publicationYear: ???)
]
struct Book {
var name: String
var publicationYear: Int?
}
Book(name: "Harry potter le retour à Poudlard", publicationYear: nil)
If Let déballage
Unwrapping
struct HarryPotter {
var name: String
var publicationYear: Int?
}
let books = [
HarryPotter(name: "Harry Potter à l'école des sorciers", publicationYear: 1997),
HarryPotter(name: "Harry Potter et la Chambre des secrets", publicationYear: 1998),
HarryPotter(name: "Harry Potter et le Prisonnier d'Azkaban", publicationYear: 1999),
HarryPotter(name: "Harry Potter et la Coupe de feu", publicationYear: 2000),
HarryPotter(name: "Harry Potter et l'Ordre du Phénix", publicationYear: 2003),
HarryPotter(name: "Harry Potter et le Prince de sang-mêlé", publicationYear: 2005),
HarryPotter(name: "Harry Potter et les Reliques de la Mort", publicationYear: 2007),
HarryPotter(name: "Harry potter le retour à Poudlard", publicationYear: ???)
]
for book in books {
print(book.publicationYear)
}
On va rencontrer un problème avec notre valeur nil.
Si je boucle sur mon tableau pour afficher les valeurs, il arrivera un moment où la boucle rencontrera une valeur inexistante (nil) et ne saura pas quoi afficher dans la console.
Pour résoudre ce problème, on peut utiliser un if let, qui permet de déballer une valeur optionnelle et de l’utiliser dans un bloc de code spécifique. Si une valeur est présente, le premier cas sera exécuté. Sinon, on passera au second cas pour gérer l’absence de valeur.
for book in books {
if let year = book.publicationYear {
print("Le livre \(book.name) a été publié en \(year).")
} else {
print("L'année de publication du livre \(book.name) est inconnue.")
}
}
Guard let
struct HarryPotter {
var name: String
var publicationYear: Int?
}
func displayBook(book: HarryPotter?) {
guard let potterBook = book else {
print("Le livre est manquant.")
return
}
guard let year = potterBook.publicationYear else {
print("L'année de publication du livre \(potterBook.name) est inconnue.")
return
}
print("Le livre \(potterBook.name) a été publié en \(year).")
}
let livreOptionnel: HarryPotter? = HarryPotter(name: "Harry Potter et l'Ordre du Phénix", publicationYear: 2003)
displayBook(book: livreOptionnel)
displayBook(book: nil)
guard let permet de vérifier que des valeurs optionnelles existent avant de continuer l’exécution du code. Si une valeur est nil, on sort immédiatement de la fonction.
Dans notre exemple, on passe en paramètre de la fonction le type HarryPotter? en optionnel. guard let vérifie s’il y a une valeur, et si c’est le cas, il passe à la suite de son exécution. Si ce n’est pas le cas, il exécute le bloc else.
guard let est très utile pour enchaîner les vérifications de cas d’absence ou non de valeur. Pour être clair, displayBook vérifie si un livre existe. Si le livre n’existe pas, la fonction s’arrête là. Si la valeur existe, il passe à la vérification suivante et vérifie si l’année de publication existe. Si ce n’est pas le cas, il s’arrête là et sort de la fonction, et si c’est le cas, il passe à la suite et affiche l’année de publication. On peut donc enchaîner les vérifications facilement.
Déballage forcé !
Forced unwrapping
struct HarryPotter {
var name: String
var publicationYear: Int?
}
let books = [
HarryPotter(name: "Harry Potter à l'école des sorciers", publicationYear: 1997),
HarryPotter(name: "Harry Potter et la Chambre des secrets", publicationYear: 1998),
HarryPotter(name: "Harry Potter et le Prisonnier d'Azkaban", publicationYear: 1999),
HarryPotter(name: "Harry Potter et la Coupe de feu", publicationYear: 2000),
HarryPotter(name: "Harry Potter et l'Ordre du Phénix", publicationYear: 2003),
HarryPotter(name: "Harry Potter et le Prince de sang-mêlé", publicationYear: 2005),
HarryPotter(name: "Harry Potter et les Reliques de la Mort", publicationYear: 2007),
HarryPotter(name: "Harry potter le retour à Poudlard", publicationYear: nil)
]
let firstHarryPotterPublicationYear = books[0].publicationYear!
print("Le premier livre Harry Potter a été publié en \(firstHarryPotterPublicationYear).")
// La valeur est bien présente sur l'index 0, elle sera bien déballé.
let newPotterPublicationYear = books[7].publicationYear!
print("Le nouveau livre Harry Potter a été publié en \(newPotterPublicationYear).")
// La valeur est nil sur l'index 7, le programme va crash.
Opérateur de coalescence nulle ??
Nil-Coalescing Operator
struct HarryPotter {
var name: String
var publicationYear: Int?
}
let book = HarryPotter(name: "Harry potter le retour à Poudlard", publicationYear: nil)
let publicationYearMessage = "L'année de publication est \(book.publicationYear ?? 0)
Chainage optionnel
Optional Chaining
struct Author {
var name: String
var birthYear: Int?
}
struct HarryPotter {
var name: String
var publicationYear: Int?
var author: Author?
}
let books = [
HarryPotter(name: "Harry Potter à l'école des sorciers", publicationYear: 1997, author: Author(name: "J.K. Rowling", birthYear: 1965)),
HarryPotter(name: "Harry Potter et la Chambre des secrets", publicationYear: 1998, author: Author(name: "J.K. Rowling", birthYear: 1965)),
HarryPotter(name: "Harry Potter et le Prisonnier d'Azkaban", publicationYear: 1999, author: Author(name: "J.K. Rowling", birthYear: 1965)),
HarryPotter(name: "Harry Potter et la Coupe de feu", publicationYear: 2000, author: Author(name: "J.K. Rowling", birthYear: 1965)),
HarryPotter(name: "Harry Potter et l'Ordre du Phénix", publicationYear: 2003, author: nil),
HarryPotter(name: "Harry Potter et le Prince de sang-mêlé", publicationYear: 2005, author: Author(name: "J.K. Rowling", birthYear: nil)),
HarryPotter(name: "Harry Potter et les Reliques de la Mort", publicationYear: 2007, author: Author(name: "J.K. Rowling", birthYear: 1965)),
HarryPotter(name: "Harry Potter le retour à Poudlard", publicationYear: nil, author: nil)
]
for book in books {
if let authorName = book.author?.name {
print("Le livre \(book.name) a été écrit par \(authorName).")
} else {
print("L'auteur du livre \(book.name) est inconnu.")
}
}
Dans notre exemple, on utilise book.author?.name pour accéder au nom de l’auteur de manière sécurisée. Si book.author est nil, l’expression renvoie nil sans provoquer de crash.
Exercices Pratiques
Exercice Optionnel
Télécharger le playground
Accède aux consignes directement en téléchargeant le playground.
⚠️ Les consignes que tu trouveras dans le playground ne sont pas verrouillées. Fais attention à ne pas les effacer par inadvertance !
Objectif
Les optionnels t’amènent à te poser la question : Est-ce que cette variable peut ne pas avoir de valeur ? Si la réponse est oui, c’est un moyen de mieux gérer cette incertitude dans ton code.
Quiz
Après un peu de pratique, il est temps de te tester avec un petit quiz pour vérifier si tout est clair pour toi. Prends ton temps, lis bien les questions, et bonne chance.
Note
Les notions s’enchaînent ! Si tu prends un peu de recul, tu remarqueras qu’à chaque nouvelle notion, on retravaille forcément un peu sur les notions précédentes. Ça te permet de pratiquer encore et encore, et donc de mieux les assimiler. Si tu doutes (et c’est tout à fait normal), prends le temps de regarder tout ce que tu as appris depuis le début. Je suis sûr que les premières notions abordées dans ce cours te semblent déjà plus évidentes à ce stade. C’est normal, car on les répète et les consolide avec chaque nouvelle notion. Ce sera pareil pour celles que tu apprends maintenant, elles deviendront plus claires avec le temps et la pratique.
Exercices Pratiques
Exercice Optionnel
Télécharger le playground
Accède aux consignes directement en téléchargeant le playground.
⚠️ Les consignes que tu trouveras dans le playground ne sont pas verrouillées. Fais attention à ne pas les effacer par inadvertance !
Objectif
Les optionnels t’amènent à te poser la question : Est-ce que cette variable peut ne pas avoir de valeur ? Si la réponse est oui, c’est un moyen de mieux gérer cette incertitude dans ton code.
Quiz
Après un peu de pratique, il est temps de te tester avec un petit quiz pour vérifier si tout est clair pour toi. Prends ton temps, lis bien les questions, et bonne chance.
Note
Les notions s’enchaînent ! Si tu prends un peu de recul, tu remarqueras qu’à chaque nouvelle notion, on retravaille forcément un peu sur les notions précédentes. Ça te permet de pratiquer encore et encore, et donc de mieux les assimiler. Si tu doutes (et c’est tout à fait normal), prends le temps de regarder tout ce que tu as appris depuis le début. Je suis sûr que les premières notions abordées dans ce cours te semblent déjà plus évidentes à ce stade. C’est normal, car on les répète et les consolide avec chaque nouvelle notion. Ce sera pareil pour celles que tu apprends maintenant, elles deviendront plus claires avec le temps et la pratique.