Instruction select du langage Go

Instruction conditionnelle du langage Go

select est une structure de contrôle en Go, similaire à l'instruction switch.

L'instruction select ne peut être utilisée que pour des opérations sur les canaux ; chaque case doit être une opération sur un canal, soit un envoi, soit une réception.

L'instruction select écoute les opérations sur tous les canaux spécifiés ; dès que l'un des canaux est prêt, le bloc de code correspondant est exécuté.

Si plusieurs canaux sont prêts, l'instruction select en choisit un au hasard à exécuter. Si aucun des canaux n'est prêt, le code du bloc default est exécuté.

Syntaxe

La syntaxe de l'instruction select dans le langage de programmation Go est la suivante :


select {
  case <- channel1:
    // Code à exécuter
  case value := <- channel2:
    // Code à exécuter
  case channel3 <- value:
    // Code à exécuter

    // Vous pouvez définir n'importe quel nombre de cas

  default:
    // Code exécuté lorsque aucun des canaux n'est prêt
}

Ce qui suit décrit la syntaxe de l'instruction select :

  • Chaque cas doit être un canal.
  • Toutes les expressions de canal sont évaluées.
  • Toutes les expressions en cours d'envoi seront évaluées
  • Si l'un des canaux peut s'exécuter, il est exécuté ; les autres sont ignorés.
  • Si plusieurs cas peuvent s'exécuter, select choisira de manière aléatoire et équitable l'un d'eux à exécuter, et les autres ne seront pas exécutés.
    Sinon :
    1. S'il existe une clause default, elle est exécutée.
    2. S'il n'y a pas de clause default, select bloquera jusqu'à ce qu'un canal puisse s'exécuter ; Go ne réévaluera pas les canaux ni les valeurs.

Exemple

Démonstration d'application de l'instruction select :

Exemple

package main

import (
    "fmt"
    "time"
)

func main() {

    c1 := make(chan string)
    c2 := make(chan string)

    go func() {
        time.Sleep(1 * time.Second)
        c1 <- "one"
    }()
    go func() {
        time.Sleep(2 * time.Second)
        c2 <- "two"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        }
    }
}

Le résultat d'exécution du code ci-dessus est :

received one
received two

Dans l'exemple ci-dessus, nous avons créé deux canaux, c1 et c2.

L'instruction select attend des données provenant de deux canaux. Si des données sont reçues sur c1, elle affiche "received one" ; si des données sont reçues sur c2, elle affiche "received two".

Dans l'exemple suivant, nous définissons deux canaux et démarrons deux goroutines pour recevoir des données de ces canaux. Dans la fonction main, nous utilisons une instruction select pour effectuer une sélection non bloquante entre les deux canaux. Si aucun des canaux n'a de données disponibles, l'instruction dans la clause default est exécutée.

Après l'exécution de l'exemple suivant, il recevra continuellement des données provenant des deux canaux. Lorsqu'aucun des canaux n'a de données disponibles, il affichera "no message received".

Exemple

package main

import "fmt"

func main() {
  // Définir deux canaux
  ch1 := make(chan string)
  ch2 := make(chan string)

  // Lancer deux goroutines, chacune recevant des données depuis l'un des canaux
  go func() {
    for {
      ch1 <- "depuis 1"
    }
  }()
  go func() {
    for {
      ch2 <- "depuis 2"
    }
  }()

  // Utiliser une instruction select pour recevoir les données des deux canaux de manière non bloquante
  for {
    select {
    case msg1 := <-ch1:
      fmt.Println(msg1)
    case msg2 := <-ch2:
      fmt.Println(msg2)
    default:
      // Si aucun des canaux n'a de données disponible, exécutez les instructions ici
      fmt.Println("aucun message reçu")
    }
  }
}

Instruction conditionnelle du langage Go

autres extensions