Flux de contrôle avec instructions switch
Comme les autres langages de programmation, Go prend en charge les instructions switch
. Vous pouvez utiliser les instructions switch
pour éviter le chaînage de plusieurs instructions if
. En utilisant des instructions switch
, vous évitez la difficulté de gérer et de lire le code qui comprend de nombreuses instructions if
. Ces instructions rendent également les conditions compliquées plus faciles à construire. Examinez les instructions switch
dans les sections suivantes.
Syntaxe switch de base
À l’instar de l’instruction if
, la condition switch
ne requiert pas de parenthèses. Dans sa forme la plus simple, une instruction switch
se présente comme suit :
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
sec := time.Now().Unix()
rand.Seed(sec)
i := rand.Int31n(10)
switch i {
case 0:
fmt.Print("zero...")
case 1:
fmt.Print("one...")
case 2:
fmt.Print("two...")
}
fmt.Println("ok")
}
Si vous exécutez le code précédent plusieurs fois, vous verrez une sortie différente à chaque fois. (Mais si vous exécutez le code dans le terrain de jeu Go, vous obtenez le même résultat à chaque fois. Ceci est l’une des limitations du service.)
Go compare chaque cas de l’instruction switch
jusqu’à ce qu’il trouve une correspondance pour la condition. Toutefois, notez que le code précédent ne couvre pas tous les cas possibles des valeurs de la variable num
. Si num
finit par être 5
, la sortie du programme est ok
.
Vous pouvez également être plus précis sur le cas d’usage par défaut et l’inclure comme suit :
switch i {
case 0:
fmt.Print("zero...")
case 1:
fmt.Print("one...")
case 2:
fmt.Print("two...")
default:
fmt.Print("no match...")
}
Notez que pour le cas default
, vous n’écrivez pas d’expression de validation. La valeur de la variable i
est validée par rapport aux instructions case
et le cas default
gère toutes les valeurs non validées.
Utiliser plusieurs expressions
Parfois, plusieurs expressions correspondent à une seule instruction case
. Dans Go, si vous souhaitez qu’une instruction case
inclue plusieurs expressions, séparez-les par des virgules (,
). Cette technique vous permet d’éviter les doublons de code.
L’exemple de code suivant montre comment inclure plusieurs expressions.
package main
import "fmt"
func location(city string) (string, string) {
var region string
var continent string
switch city {
case "Delhi", "Hyderabad", "Mumbai", "Chennai", "Kochi":
region, continent = "India", "Asia"
case "Lafayette", "Louisville", "Boulder":
region, continent = "Colorado", "USA"
case "Irvine", "Los Angeles", "San Diego":
region, continent = "California", "USA"
default:
region, continent = "Unknown", "Unknown"
}
return region, continent
}
func main() {
region, continent := location("Irvine")
fmt.Printf("John works in %s, %s\n", region, continent)
}
Notez que les valeurs que vous incluez dans les expressions de l’instruction case
correspondent au type de données de la variable que l’instruction switch
valide. Si vous incluez une valeur entière comme nouvelle instruction case
, le programme ne sera pas compilé.
Appeler une fonction
Une switch
peut également appeler une fonction. À partir de cette fonction, vous pouvez écrire des instructions case
pour les valeurs de retour possibles. Par exemple, le code suivant appelle la fonction time.Now()
. La sortie imprimée dépend du jour de la semaine.
package main
import (
"fmt"
"time"
)
func main() {
switch time.Now().Weekday().String() {
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday":
fmt.Println("It's time to learn some Go.")
default:
fmt.Println("It's the weekend, time to rest!")
}
fmt.Println(time.Now().Weekday().String())
}
Quand vous appelez une fonction à partir d’une instruction switch
, vous pouvez modifier sa logique sans modifier l’expression, car vous validez toujours ce que la fonction retourne.
Vous pouvez également appeler une fonction à partir d’une instruction case
. Utilisez cette technique, par exemple, pour faire correspondre un modèle particulier à l’aide d’une expression régulière. Voici un exemple :
package main
import "fmt"
import "regexp"
func main() {
var email = regexp.MustCompile(`^[^@]+@[^@.]+\.[^@.]+`)
var phone = regexp.MustCompile(`^[(]?[0-9][0-9][0-9][). \-]*[0-9][0-9][0-9][.\-]?[0-9][0-9][0-9][0-9]`)
contact := "foo@bar.com"
switch {
case email.MatchString(contact):
fmt.Println(contact, "is an email")
case phone.MatchString(contact):
fmt.Println(contact, "is a phone number")
default:
fmt.Println(contact, "is not recognized")
}
}
Notez que le bloc switch
n’a pas d’expression de validation. Nous parlerons de ce concept dans la section suivante.
Omettre une condition
Dans Go, vous pouvez omettre une condition dans une instruction switch
comme dans une instruction if
. Ce modèle est similaire à la comparaison d’une valeur true
comme si vous forciez l’exécution de l’instruction switch
en permanence.
Voici un exemple d’écriture d’une instruction switch
sans condition :
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
r := rand.Float64()
switch {
case r > 0.1:
fmt.Println("Common case, 90% of the time")
default:
fmt.Println("10% of the time")
}
}
Le programme exécute toujours ce type d’instruction switch
, car la condition est toujours true. Un bloc switch
conditionnel peut être plus facile à gérer qu’une longue chaîne d’instructions if
et else if
.
Appliquer la logique au cas suivant
Dans certains langages de programmation, vous devez écrire un mot clé break
à la fin de chaque instruction case
. Mais dans Go, lorsque la logique se trouve dans un seul cas, elle quitte le bloc switch
, sauf si vous l’arrêtez explicitement. Pour que la logique passe au cas immédiat suivant, utilisez le mot clé fallthrough
.
Pour mieux comprendre ce modèle, examinez l’exemple de code suivant.
package main
import (
"fmt"
)
func main() {
switch num := 15; {
case num < 50:
fmt.Printf("%d is less than 50\n", num)
fallthrough
case num > 100:
fmt.Printf("%d is greater than 100\n", num)
fallthrough
case num < 200:
fmt.Printf("%d is less than 200", num)
}
}
Exécutez le code et analysez la sortie :
15 is less than 50
15 is greater than 100
15 is less than 200
Voyez-vous un problème ?
Notez que, étant donné que la valeur de num
est 15 (inférieur à 50), il correspond au premier cas. Mais num
n’est pas supérieur à 100. Et étant donné que la première instruction case
a un mot clé fallthrough
, la logique passe immédiatement à l’instruction case
suivante sans valider le cas. Vous devez donc être prudent lorsque vous utilisez le mot clé fallthrough
. Vous ne souhaitez peut-être pas obtenir le comportement créé par ce code.