• 8 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 10/10/2023

Énumérez des cas

Pour aller plus loin, nous allons découvrir un nouveau modèle de données nommées ! En Swift, il existe trois modèles de données nommées :

  • les classes ;

  • les structures ;

  • les énumérations.

Ce cours fait la part belle aux classes : vous savez de quoi il s'agit.

Les structures ressemblent beaucoup aux classes et sont très utiles en Swift, mais nous ne verrons leur utilisation qu'au prochain cours sur iOS.

Et les énumérations, eh bien c'est le sujet de ce chapitre !

Découvrez les énumérations

Comme les classes, les énumérations sont des modèles de données nommées. C'est-à-dire qu'elles vont nous permettre de modéliser nos données en définissant un nouveau type. C'est ce qu'on a fait avec nos classes jusqu'à présent. On a créé un modèle de données simple à comprendre, avec trois nouveaux types : un bus, une route et des sections de route. Les énumérations ont une mission similaire, mais pour des usages un peu différents.

Le rôle d'une énumération est très simple : elle permet d'énumérer des cas. Et il y a plein de moments où c'est utile. Laissez-moi vous donner quelques exemples :

  1. Quand vous cherchez votre direction avec une boussole, il y a quatre cas possibles : nord, sud, est, ouest.

  2. Si quelqu’un vous demande votre couleur préférée, il y a huit possibilités : noir, marron, rouge, orange, jaune, vert, bleu ou violet.

  3. Si vous voulez présenter un message d’erreur à un utilisateur, vous pouvez définir plusieurs cas identifiables, comme : Vous n'êtes pas connecté, Connexion Internet faible ou Vous n'avez pas l'autorisation.

Avec les énumérations, on va pouvoir nommer tous ces cas. En reprenant les exemples précédents, cela donnerait :

  1. Type : Direction / Cas : north, south, east, west.

  2. Type : Color / Cas : black, brown, red, orange, yellow, green, blue, violet.

  3. Type : Error / Cas : not connected, low signal, unauthorized.

On a donc un type générique qui contient différents cas. Sans plus attendre, je vous propose de vous montrer tout de suite comment déclarer ces 3 énumérations en Swift :

// 1

enum Direction {
   case north
   case south
   case east
   case west

}

// 2
enum Color {
   case black
   case brown
   case red
   case orange
   case yellow
   case green
   case blue
   case violet
}

// 3

enum Error {
   case notConnected
   case lowSignal
   case unauthorized
}

Comme vous pouvez le constater, cela ressemble aux déclarations de classe. Ici on a le mot-clé enum qui permet de déclarer l'énumération, et ensuite le mot-clé case à l'intérieur, qui permet à chaque fois d'ajouter un nouveau cas.

Il existe une syntaxe réduite où l'on peut tout écrire sur une seule ligne. Il suffit d'utiliser la ,entre deux cas :

// 1

enum Direction {
case north, south, east, west
}

// 2

enum Color {
   case black, brown,, red, orange, yellow, green, blue, violet
}

// 3
enum Error {
   case notConnected, lowSignal, unauthorized
}

Utilisez les énumérations

Pour utiliser une énumération, on utilise le nom de l'énumération suivi du . , suivi du nom du cas. Par exemple :

var connectionError = Error.notConnected
var connectionError = Error.notConnected
connectionError = .lowSignal // Le type est connu grâce à la déclaration précédente
let dir: Direction = .north // Le type est annoté

Utilisez les énumérations et switch

On utilise très souvent les énumérations avec les switch . C'est logique, car le switch est une structure de contrôle qui permet de naviguer entre plusieurs cas. C'est ce que nous allons faire ici avec nos types de sections de route. Tout d'abord, je vous propose de créer une énumération qui décrit nos trois types de sections de route :

enum RoadSectionType {
   case plain
   case home
   case school
}

Maintenant, nous allons pouvoir ajouter à notre classe RoadSection la propriété type :

class RoadSection {
   var type: RoadSectionType

   init() {
      canvas.createRoadSection()
   }
}

Nous allons désormais modifier notre init . Nous allons créer une initialisation qui prend en compte le paramètre type. Cela va nous permettre de dessiner sur le canevas la partie de route correspondant au type choisi :

init(type: RoadSectionType) {
      self.type = type
}

Rien de nouveau ici, j'utilise une initialisation avec paramètre, comme on l'a vu dans les chapitres précédents.

Je vais maintenant rajouter le switch :

init(type: RoadSectionType) {
   self.type = type
   switch type {
   case .plain:
      canvas.createRoadSection()
   case .home:
      canvas.createHomeRoadSection()
   case .school:
      canvas.createSchoolRoadSection()
   }
}

Plusieurs choses à noter :

  • Pour chaque cas, j'utilise la méthode appropriée du canevas pour dessiner la section.

  • Je fais le switch sur la variable type qui a pour type RoadSectionType . Je peux donc utiliser les cas directement avec le point, sans rappeler RoadSectionType avant.

  • Le switch en Swift doit être exhaustif. Cela veut dire que tous les cas doivent être pris en compte dans un switch. C'est la raison pour laquelle vous avez systématiquement utilisé le mot-clé default jusqu'à présent, qui permet de couvrir tous les autres cas. Ici, nous utilisons une énumération qui ne contient que trois cas. Nous couvrons ces trois cas avec le switch, donc inutile d'utiliser default .

Avec cette nouvelle initialisation, nous pouvons maintenant créer facilement les sections de route du type de notre choix, comme ceci :

RoadSection(type: .plain)
RoadSection(type: .home)
RoadSection(type: .school)

Dans le prochain chapitre, nous allons encore simplifier ceci avec l'héritage !

Découvrez la vérité sur les optionnels

En effet, je vais vous révéler la vérité sur les optionnels ! Vous êtes prêts ?

Les optionnels... sont... tout simplement... des... ÉNUMÉRATIONS ! Eh oui ! Laissez-moi vous montrer à quoi ils ressemblent :

enum Optional<T> {
   case none
   case some(T)
}

Donc un optionnel, c'est deux cas. Soit rien (none), soit quelque chose (d'un type précis). Et c'est exactement ce que vous connaissez des optionnels. Allons plus loin et jouons au jeu des équivalences :

let x: String? est égale à let x = Optional.none (si la valeur est nil) ou Optional.some(la valeur). Pour var y = x! ou let x: String? = '' '' if let y = x{}, on pourrait les réécrire avec un switch.
Les équivalences

Ces équivalences vous montrent des utilisations assez avancées des énumérations (notamment à cause de cette histoire de <T>  ). Ne vous arrêtez pas à ça, et prenez juste le temps de comprendre le fait que les optionnels sont des énumérations, et ce que cela veut dire concrètement.

J'espère que cela vous permettra de vous servir correctement des optionnels !

Ajoutez des valeurs brutes

Jusqu'à présent, nos énumérations sont des coquilles vides. Cela signifie qu'elles ne contiennent rien. Elles nous permettent de définir des cas, mais les cas ne contiennent pas de données. Sachez qu'en Swift, on peut associer à chaque cas une valeur. Reprenons un des exemples précédents :

enum Error {
   case notConnected
   case lowSignal
   case unauthorized
}

Cela pourrait être pratique que les cas contiennent un message d'erreur à afficher à notre utilisateur. Pour cela, nous allons préciser le type de la valeur brute contenue dans chaque cas, et ensuite leur donner des valeurs. Voici la syntaxe :

enum Error: String {
   case notConnected = "Vous n'êtes pas connecté."
   case lowSignal = "Veuillez vérifier votre connexion internet."
   case unauthorized = "Vous n'êtes pas autorisé à effectuer cette action."
}

Je définis donc d'abord que la valeur brute a pour type String, et ensuite je l'attribue à chacun des cas. Ensuite, pour l'obtenir, j'utilise la propriété rawValue .

let connectionError = Error.notConnected.rawValue // Cela affiche "Vous n'êtes pas connecté.
// 1
enum Direction: String {
   case north
   case south
   case east
   case west
}

// 2
enum Planet: Int {
   case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
var dir = Direction.north.rawValue // Contient "nord"
var earth = Planet.earth.rawValue // Contient 3

À vous de jouer !

Pratiquez l'énumération dans cet exercice !

Pour accéder à la solution :

  1. Soumettez votre projet avec le bouton "Submit" en haut à droite, 

  2. Cliquez sur le titre de l'exercice en haut à gauche de la fenêtre,

  3. Puis sur "OCswiftpoo",

  4. Cliquez sur "Fork the solution".

En résumé

  • Les énumérations, comme les classes et les structures, sont des modèles de données nommés.

  • Les énumérations permettent d'énumérer des cas.

  • La syntaxe de création d'une énumération est la suivante :

enum NameOfEnumeration {
   case nameOfCase1
   case nameOfCase2
   case nameOfCase3
}
  • Pour utiliser une énumération, on utilise le nom de l'énumération suivi de. , puis du nom du cas : NameOfEnumeration.nameOfCase1 .

  • On utilise très souvent les énumérations avec lesswitch .

  • Les optionnels sont des énumérations.

  • Les énumérations peuvent contenir des valeurs, appelées valeurs brutes. Ces valeurs doivent être du même type pour tous les cas d'une énumération. On les rajoute comme ceci :

enum NameOfEnumeration: Type {
   case nameOfCase1 = value1
   case nameOfCase2 = value2
   case nameOfCase3 = value3
}
  • La valeur brute est contenue dans la propriété rawValue .

Vous avez désormais une compétence de plus dans votre bagage POO et Swift ! Maintenant vous allez pouvoir vous servir des énumérations et de l’héritage pour améliorer notre projet dans le prochain chapitre.

Exemple de certificat de réussite
Exemple de certificat de réussite