Sök…


Introduktion

Det select sökordet ger en enkel metod för att arbeta med kanaler och utföra mer avancerade uppgifter. Det används ofta för ett antal syften: - Hantera timeouts. - När det finns flera kanaler att läsa från läser valet slumpmässigt från en kanal som har data. - Tillhandahålla ett enkelt sätt att definiera vad som händer om ingen data finns tillgänglig på en kanal.

Syntax

  • Välj {}
  • välj {case true:}
  • välj {case incomingData: = <-someChannel:}
  • välj {standard:}

Enkel Välj Arbeta med kanaler

I det här exemplet skapar vi en goroutine (en funktion som körs i en separat tråd) som accepterar en chan parameter och helt enkelt slingar och skickar information till kanalen varje gång.

I main vi en for loop och en select . Den select blockerar behandling tills en av case uttalanden blir sann. Här har vi förklarat två fall; det första är när information kommer via kanalen, och det andra är om inget annat fall inträffar, vilket är känt som 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)
        }
    }
}

Prova på Go Playground!

Använd välj med timeouts

Så här har jag tagit bort for slingor och gjort en timeout genom att lägga till ett andra case till select som kommer tillbaka efter 3 sekunder. Eftersom den select bara väntar tills ALLA fall är sanna, avfyras det andra case , och sedan slutar vårt manus, och chatter() aldrig en chans att avsluta.

// 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow