Un switch compare une valeur à une liste de cas et exécute le premier qui correspond. Contrairement à C, Java et JavaScript, un cas Go ne passe pas au suivant, donc il n'y a pas de break à oublier.
Les cas sont testés de haut en bas, et seul le premier cas correspondant s'exécute. default s'exécute quand rien ne correspond ; il est facultatif et peut apparaître n'importe où dans la liste, même si on le place en dernier par convention.
Plusieurs valeurs par cas
case "sat", "sun": correspond à l'une ou l'autre valeur. C'est ainsi que Go exprime ce que C fait avec des cas vides empilés. Tout type comparable fonctionne : chaînes, nombres, runes, booléens, pointeurs, et types nommés comme les enums :
Deux cas avec la même valeur constante sont une erreur de compilation :
./main.go:10:7: duplicate case 1 (constant of type int) in expression switch
./main.go:8:7: previous case
Switch sans condition
Omettez l'expression et chaque cas devient un test booléen. C'est la forme plus propre qu'offre Go pour une longue chaîne if/else if :
switch { est un raccourci pour switch true {. Comme le premier cas vrai l'emporte, l'ordre compte : bmi < 25 n'est atteint que si bmi < 18.5 était faux, donc chaque cas peut supposer que ceux du dessus ont échoué.
Switch avec une instruction d'initialisation
Comme if, un switch peut commencer par une courte instruction. Les variables qui y sont déclarées ont une portée limitée au switch :
L'instruction d'initialisation peut aussi se combiner avec un switch sans expression : switch n := len(items); { case n == 0: ... }.
fallthrough
Quand vous voulez vraiment continuer dans le cas suivant, écrivez fallthrough comme dernière instruction d'un cas. Il transfère le contrôle au corps du cas suivant sans évaluer sa condition :
Le niveau 2 affiche write puis read, en cumulant les permissions vers le bas. Les conditions des cas suivants ne sont pas testées : après fallthrough depuis case 2, case 1 s'exécute alors que level vaut 2.
Règles de fallthrough :
- Ce doit être la dernière instruction du cas.
- Il ne peut pas apparaître dans le dernier cas :
cannot fallthrough final case in switch. - Il n'est pas permis dans un type switch.
En pratique, fallthrough est rare dans le code Go. Les valeurs multiples par cas couvrent le besoin courant, et des appels de fonction explicites sont généralement plus clairs qu'une chaîne de fallthrough.
break dans un switch
break dans un cas quitte le switch. Les cas se terminent seuls, donc vous n'en avez besoin que pour quitter un cas plus tôt. Le piège est un switch à l'intérieur d'une boucle :
Sans l'étiquette loop, break termine le switch et la boucle continue jusqu'à "c". continue, en revanche, se rapporte toujours à la boucle englobante, puisqu'un switch n'est pas une boucle.
Switch sur les types
Un type switch branche sur le type dynamique d'une valeur interface, avec la forme spéciale v.(type) :
Dans un cas avec un seul type, x a ce type (len(x) fonctionne dans le cas string). Dans un cas qui liste plusieurs types, x garde le type interface. La page sur les assertions de type traite en détail les type switches et l'assertion v.(T).
Ce que le switch de Go fait différemment
| Comportement | C, Java, JavaScript | Go |
|---|---|---|
| Passer au cas suivant | par défaut | seulement avec fallthrough |
break à la fin de chaque cas | obligatoire | inutile |
| Plusieurs valeurs par cas | cas vides empilés | case a, b, c: |
| Valeurs des cas | constantes (surtout) | n'importe quelle expression, évaluée de haut en bas |
| Valeur du switch | types entiers (C) | n'importe quel type comparable |
| Pas d'expression de switch | interdit | switch { case cond: } |
Les expressions des cas n'ont pas besoin d'être des constantes. case limit(), max + 1: est légal ; elles sont évaluées dans l'ordre jusqu'à ce qu'une corresponde, donc les suivantes peuvent ne jamais s'exécuter.
Exhaustivité
Go ne vérifie pas qu'un switch sur un enum couvre toutes les valeurs. Ajoutez un default qui journalise, renvoie une erreur ou provoque un panic pour les valeurs inattendues, ou utilisez le linter exhaustive (inclus dans golangci-lint) pour que les cas manquants soient signalés à la compilation.
Questions fréquentes
Le switch de Go passe-t-il au cas suivant ?
Non. Un cas Go se termine automatiquement au case suivant ; vous n'écrivez jamais break pour l'arrêter. Si vous voulez que l'exécution continue dans le corps du cas suivant, écrivez fallthrough comme dernière instruction du cas. Il saute sans condition, sans tester la condition du cas suivant.
Comment tester plusieurs valeurs dans un seul cas en Go ?
Listez-les séparées par des virgules : case "sat", "sun":. Le cas s'exécute si la valeur du switch est égale à l'une d'elles. Cela remplace les cas vides empilés que vous écririez en C ou en Java.
Qu'est-ce qu'un switch sans condition en Go ?
switch { case x < 0: ...; case x == 0: ...; default: ... }. Sans expression après switch, chaque cas est une condition booléenne et le premier cas vrai s'exécute. C'est le remplacement idiomatique d'une longue chaîne if/else if.
Que fait break dans un switch en Go ?
Il termine le switch, pas une boucle for englobante. C'est rarement nécessaire, puisque les cas se terminent seuls, mais cela surprend ceux qui écrivent break dans un switch à l'intérieur d'une boucle en s'attendant à quitter la boucle. Utilisez un break étiqueté ou return pour cela.