Buscar..


Introducción

La palabra clave select proporciona un método fácil para trabajar con canales y realizar tareas más avanzadas. Se utiliza con frecuencia para varios propósitos: - Tiempo de espera de manejo. - Cuando hay varios canales para leer, la selección se leerá aleatoriamente desde un canal que tenga datos. - Proporcionar una manera fácil de definir qué sucede si no hay datos disponibles en un canal.

Sintaxis

  • seleccione {}
  • seleccione {caso verdadero:}
  • seleccione {case incomingData: = <-someChannel:}
  • seleccione {predeterminado:}

Simple Seleccione Trabajar con Canales

En este ejemplo, creamos una goroutine (una función que se ejecuta en un subproceso independiente) que acepta un parámetro chan , y simplemente realiza un bucle, enviando información al canal cada vez.

En lo main tenemos un bucle for y un select . La select bloqueará el procesamiento hasta que una de las declaraciones de case convierta en verdadera. Aquí hemos declarado dos casos; la primera es cuando la información llega a través del canal, y la otra es si no ocurre ningún otro caso, lo que se conoce como default .

// Use of the select statement with channels (no timeouts)
package main

import (
    "fmt"
    "time"
)

// Function that is "chatty"
// Takes a single parameter a channel to send messages down
func chatter(chatChannel chan<- string) {
    // Clean up our channel when we are done.
    // The channel writer should always be the one to close a channel.
    defer close(chatChannel)

    // loop five times and die
    for i := 1; i <= 5; i++ {
        time.Sleep(2 * time.Second) // sleep for 2 seconds
        chatChannel <- fmt.Sprintf("This is pass number %d of chatter", i)
    }
}

// Our main function
func main() {
    // Create the channel
    chatChannel := make(chan string, 1)

    // start a go routine with chatter (separate, non blocking)
    go chatter(chatChannel)

    // This for loop keeps things going while the chatter is sleeping
    for {
        // select statement will block this thread until one of the two conditions below is met
        // because we have a default, we will hit default any time the chatter isn't chatting
        select {
        // anytime the chatter chats, we'll catch it and output it
        case spam, ok := <-chatChannel:
            // Print the string from the channel, unless the channel is closed
            // and we're out of data, in which case exit.
            if ok {
                fmt.Println(spam)
            } else {
                fmt.Println("Channel closed, exiting!")
                return
            }
        default:
            // print a line, then sleep for 1 second.
            fmt.Println("Nothing happened this second.")
            time.Sleep(1 * time.Second)
        }
    }
}

Pruébalo en el Go Playground!

Usando seleccionar con tiempos de espera

Así que aquí, he eliminado los bucles for , e hice un tiempo de espera agregando un segundo case a la select que regresa después de 3 segundos. Debido a que la select solo espera hasta que CUALQUIER caso sea verdadero, el segundo case dispara, y luego nuestro script termina, y el chatter() ni siquiera tiene la oportunidad de terminar.

// Use of the select statement with channels, for timeouts, etc.
package main

import (
    "fmt"
    "time"
)

// Function that is "chatty"
//Takes a single parameter a channel to send messages down
func chatter(chatChannel chan<- string) {
    // loop ten times and die
    time.Sleep(5 * time.Second) // sleep for 5 seconds
    chatChannel<- fmt.Sprintf("This is pass number %d of chatter", 1)
}

// out main function
func main() {
    // Create the channel, it will be taking only strings, no need for a buffer on this project
    chatChannel := make(chan string)
    // Clean up our channel when we are done
    defer close(chatChannel)

    // start a go routine with chatter (separate, no blocking)
    go chatter(chatChannel)

    // select statement will block this thread until one of the two conditions below is met
    // because we have a default, we will hit default any time the chatter isn't chatting
    select {
    // anytime the chatter chats, we'll catch it and output it
    case spam := <-chatChannel:
        fmt.Println(spam)
    // if the chatter takes more than 3 seconds to chat, stop waiting
    case <-time.After(3 * time.Second):
        fmt.Println("Ain't no time for that!")
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow