
Aiguillage (`switch` - bases)
Découvrez l'instruction `switch` en Go, une alternative puissante et lisible aux longues chaînes `if-else if` pour évaluer une expression contre plusieurs valeurs possibles.
Alternative élégante : Introduction au `switch`
Lorsque vous devez comparer une seule variable ou expression à une série de valeurs constantes distinctes, les structures `if-else if-else` peuvent devenir longues et répétitives. Go propose une alternative plus claire et souvent plus efficace pour ce type de scénario : l'instruction `switch`. Elle permet d'"aiguiller" l'exécution du code vers différents blocs (`case`) en fonction de la valeur d'une expression.
Le `switch` en Go est plus flexible et puissant que dans certains autres langages (comme C ou Java). Nous allons commencer par explorer ses fonctionnalités de base : comparer une expression à des valeurs littérales.
L'idée fondamentale est d'évaluer une `expression` une seule fois, puis de comparer son résultat à chaque `valeur` spécifiée dans les clauses `case`. Dès qu'une correspondance est trouvée, le bloc de code associé à ce `case` est exécuté.
Syntaxe fondamentale du `switch`
La structure de base d'un `switch` en Go est la suivante :
switch expression {
case valeur1:
// Bloc de code exécuté si expression == valeur1
case valeur2:
// Bloc de code exécuté si expression == valeur2
case valeur3, valeur4: // Plusieurs valeurs possibles pour un même cas
// Bloc de code exécuté si expression == valeur3 OU expression == valeur4
// ... autres cases ...
default:
// Bloc de code exécuté si aucune des valeurs précédentes ne correspond
}Points clés de cette syntaxe :
- L'`expression` après le mot-clé `switch` est évaluée une seule fois. Son type peut être n'importe quel type comparable en Go (entiers, flottants, booléens, chaînes, pointeurs, etc.).
- Chaque `case` est suivi d'une ou plusieurs `valeurs` (séparées par des virgules si multiples) et de deux-points `:`. Les valeurs doivent être des constantes ou des littéraux compatibles avec le type de l'`expression`.
- Le bloc de code associé à un `case` s'étend jusqu'au `case` suivant ou jusqu'à l'accolade fermante `}` du `switch`.
- La clause `default` est optionnelle. Si présente, son bloc de code est exécuté si l'`expression` ne correspond à aucune des `valeurs` des autres `case`.
- Comme pour `if` et `for`, les accolades `{}` sont obligatoires autour du corps du `switch`.
Comportement par défaut : Pas de `fallthrough` automatique
Une différence majeure et très importante par rapport aux `switch` de langages comme C, C++ ou Java est qu'en Go, l'exécution ne passe pas automatiquement d'un `case` au suivant (pas de "fallthrough" implicite). Dès qu'un `case` correspond et que son bloc de code est exécuté, l'instruction `switch` se termine immédiatement.
Cela signifie que vous n'avez pas besoin d'ajouter une instruction `break` à la fin de chaque `case` pour empêcher l'exécution de continuer dans le cas suivant. Le `break` est implicite en Go. Ce comportement élimine une source fréquente d'erreurs dans d'autres langages où l'oubli d'un `break` peut entraîner des bugs subtils.
Exemple illustrant ce comportement :
package main
import "fmt"
func main() {
jour := "Mardi"
switch jour {
case "Lundi":
fmt.Println("Début de semaine.")
case "Mardi":
fmt.Println("On avance.") // Seul ce message sera affiché
case "Mercredi":
fmt.Println("Milieu de semaine.")
default:
fmt.Println("Autre jour.")
}
// L'exécution reprend ici après le switch
fmt.Println("Après le switch.")
}Ici, seul "On avance." sera affiché, car après l'exécution du `case "Mardi":`, le `switch` se termine.Le `fallthrough` explicite (usage avancé et rare)
Bien que le `break` implicite soit le comportement standard et généralement souhaité, Go fournit le mot-clé `fallthrough` pour les cas (relativement rares) où vous voulez explicitement que l'exécution continue dans le bloc de code du `case` suivant, sans évaluer la condition de ce `case` suivant.
L'utilisation de `fallthrough` doit être intentionnelle et est souvent un signe que la logique pourrait être repensée. Cependant, elle existe pour des scénarios spécifiques. Elle doit être la dernière instruction du bloc `case`.
Exemple (peu idiomatique, juste pour illustration) :
package main
import "fmt"
func main() {
taille := 2
switch taille {
case 1:
fmt.Println("Taille 1")
fallthrough // Explicitement passer au cas suivant
case 2:
fmt.Println("Taille 1 ou 2") // Sera exécuté à cause du fallthrough
fallthrough // Explicitement passer au cas suivant
case 3:
fmt.Println("Taille 1, 2 ou 3") // Sera exécuté à cause du fallthrough
default:
fmt.Println("Autre taille")
}
}Ce code affichera "Taille 1 ou 2" et "Taille 1, 2 ou 3" car `fallthrough` force l'exécution à continuer. En pratique, on préfère souvent utiliser des `case` avec plusieurs valeurs (`case 1, 2:`) ou des structures `if` pour une meilleure clarté.Comparer plusieurs valeurs et utiliser `default`
La possibilité de lister plusieurs valeurs dans un même `case` (séparées par des virgules) rend le `switch` très pratique pour regrouper des conditions similaires.
La clause `default` agit comme un `else` final dans une chaîne `if-else if`. Elle est exécutée si aucune des valeurs spécifiées dans les `case` précédents ne correspond à l'expression du `switch`. Elle est facultative et peut être placée n'importe où dans le `switch`, bien que par convention, elle soit généralement placée en dernier.
Exemple combinant ces aspects :
package main
import "fmt"
func main() {
lettre := 'C'
switch lettre {
case 'A', 'E', 'I', 'O', 'U', 'Y':
fmt.Printf("%c est une voyelle.\n", lettre)
case 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M',
'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Z':
fmt.Printf("%c est une consonne.\n", lettre)
default:
fmt.Printf("%c n'est pas une lettre de l'alphabet usuel.\n", lettre)
}
}Ici, `lettre` ('C') correspond au deuxième `case`, et le message "C est une consonne." est affiché. Si `lettre` avait été '5', le `default` aurait été exécuté.Quand utiliser `switch` ?
L'instruction `switch` de base est particulièrement adaptée lorsque vous avez besoin de :
- Comparer une seule variable ou expression à une liste de valeurs constantes connues.
- Exécuter différents blocs de code en fonction de ces valeurs spécifiques.
- Améliorer la lisibilité par rapport à une longue série de `if-else if` pour des comparaisons d'égalité simples.
Go offre des formes plus avancées de `switch` (comme le `switch` sans expression ou le `type switch`) qui étendent encore ses capacités et seront abordées ultérieurement. Pour l'instant, maîtriser cette forme de base vous fournit déjà un outil puissant pour structurer votre logique conditionnelle de manière claire et concise.