Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Select Statement Patterns in Go

Introduction

The select statement in Go is a powerful tool used for handling multiple channel operations. It allows a goroutine to wait on multiple communication operations, proceeding with the first one that is ready. This tutorial will cover the various patterns of using the select statement, along with detailed explanations and examples.

Basic Select Statement

In its simplest form, the select statement waits until one of its cases can proceed, then it executes that case. If multiple cases are ready, one of them is chosen at random.

package main

import (
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
        time.Sleep(2 * time.Second)
        ch1 <- "First channel"
    }()

    go func() {
        time.Sleep(1 * time.Second)
        ch2 <- "Second channel"
    }()

    select {
    case msg1 := <-ch1:
        fmt.Println(msg1)
    case msg2 := <-ch2:
        fmt.Println(msg2)
    }
}
Output: Second channel

Default Case

The select statement can also include a default case, which executes if no other case is ready. This can be useful for non-blocking communication.

package main

import "fmt"

func main() {
    ch := make(chan string)

    select {
    case msg := <-ch:
        fmt.Println(msg)
    default:
        fmt.Println("No message received")
    }
}
Output: No message received

Timeouts

Timeouts can be implemented using the select statement by utilizing the time.After function. This function returns a channel that sends the current time after a specified duration.

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan string)

    go func() {
        time.Sleep(2 * time.Second)
        ch <- "Message"
    }()

    select {
    case msg := <-ch:
        fmt.Println(msg)
    case <-time.After(1 * time.Second):
        fmt.Println("Timeout")
    }
}
Output: Timeout

Multiple Channels

The select statement can be used to wait on multiple channels simultaneously. This allows for more complex synchronization patterns.

package main

import (
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
        time.Sleep(2 * time.Second)
        ch1 <- "First channel"
    }()

    go func() {
        time.Sleep(1 * time.Second)
        ch2 <- "Second channel"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-ch1:
            fmt.Println(msg1)
        case msg2 := <-ch2:
            fmt.Println(msg2)
        }
    }
}
Output:
Second channel
First channel

Conclusion

The select statement is an essential feature in Go for handling multiple channel operations efficiently. By mastering its patterns, you can write more robust and responsive concurrent programs. This tutorial covered the basic usage, default case, implementing timeouts, and handling multiple channels using the select statement.