Select Statement in Go

List Topics
February 18, 2025
No Comments
5 min read

The select statement in Go is a powerful control structure used to handle multiple channel operations. It allows a goroutine to wait on multiple communication operations (like receiving from or sending to channels) and proceeds with whichever is ready first. It’s similar to the switch statement but specifically for channels.

1️⃣ Basic Usage of select

The select statement waits until one of the channel operations is ready and executes the corresponding case. If multiple operations are ready, it picks one at random.

🔹 Example:

Go
package main

import (
    "fmt"
    "time"
)

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

    // Sending to channels using goroutines
    go func() {
        time.Sleep(2 * time.Second)
        ch1 <- "Message from channel 1"
    }()
    
    go func() {
        time.Sleep(1 * time.Second)
        ch2 <- "Message from channel 2"
    }()

    // Using select to wait for either channel to receive data
    select {
    case msg1 := <-ch1:
        fmt.Println(msg1)
    case msg2 := <-ch2:
        fmt.Println(msg2)
    }
}

🔹 Output:

Bash
Message from channel 2

👉 In this example, since ch2 sends the message earlier, the select statement chooses the ch2 case to execute.

2️⃣ Multiple Cases

You can handle multiple channel operations using select. If none of the channels are ready, select will block until one becomes available.

🔹 Example:

Go
package main

import (
    "fmt"
    "time"
)

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

    go func() {
        time.Sleep(1 * time.Second)
        ch1 <- "Data from ch1"
    }()
    
    go func() {
        time.Sleep(2 * time.Second)
        ch2 <- "Data from ch2"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-ch1:
            fmt.Println("Received:", msg1)
        case msg2 := <-ch2:
            fmt.Println("Received:", msg2)
        }
    }
}

🔹 Output:

Bash
Received: Data from ch1
Received: Data from ch2

👉 In this example, the select waits for either ch1 or ch2 to be ready, and prints their messages as they become available.

3️⃣ Default Case

You can provide a default case in select to handle situations where none of the channels are ready. The default case will execute immediately if no other channel operation is ready.

🔹 Example:

Go
package main

import (
    "fmt"
    "time"
)

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

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

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

🔹 Output:

Bash
No message received, moving on...

👉 Here, the default case executes because no message is available yet on the channel, so it moves on without waiting.

4️⃣ Timeout Using select

The select statement can be used with timeouts to avoid waiting indefinitely for a channel operation.

🔹 Example:

Go
package main

import (
    "fmt"
    "time"
)

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

    go func() {
        time.Sleep(3 * time.Second)
        ch <- "Delayed message"
    }()

    select {
    case msg := <-ch:
        fmt.Println("Received:", msg)
    case <-time.After(2 * time.Second):
        fmt.Println("Timeout, no message received")
    }
}

🔹 Output:

Bash
Timeout, no message received

👉 In this example, since the message is delayed for 3 seconds but the timeout is set for 2 seconds, the timeout case executes first.

Summary:

  • The select statement in Go allows you to wait on multiple channel operations and proceeds with the first one that’s ready.
  • You can handle multiple cases, provide a default case for immediate execution, and implement timeouts using select.
  • It's a critical tool for working with concurrent goroutines and channels in Go, enabling more efficient communication and coordination.

Select Statement in Go

Go-তে select statement একটি শক্তিশালী কন্ট্রোল স্ট্রাকচার, যা একাধিক চ্যানেল অপারেশন পরিচালনা করতে ব্যবহৃত হয়। এটি একটি goroutine-কে একাধিক চ্যানেল অপারেশন (যেমন ডেটা পাঠানো বা গ্রহণ করা) এর মধ্যে অপেক্ষা করতে দেয় এবং যেটি প্রথমে প্রস্তুত হয়, সেটি কার্যকর করা হয়। এটি switch স্টেটমেন্টের মতো হলেও এটি বিশেষভাবে চ্যানেলের জন্য।

1️⃣ select এর মৌলিক ব্যবহার

select স্টেটমেন্ট অপেক্ষা করে যতক্ষণ না একটি চ্যানেল অপারেশন প্রস্তুত হয় এবং তারপর সেই সংশ্লিষ্ট case চালু হয়। যদি একাধিক অপারেশন প্রস্তুত থাকে, তবে এটি যেকোনো একটি র্যান্ডমভাবে নির্বাচন করে।

🔹 উদাহরণ:

Go
package main

import (
    "fmt"
    "time"
)

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

    // goroutine ব্যবহার করে চ্যানেলে ডেটা পাঠানো
    go func() {
        time.Sleep(2 * time.Second)
        ch1 <- "Message from channel 1"
    }()
    
    go func() {
        time.Sleep(1 * time.Second)
        ch2 <- "Message from channel 2"
    }()

    // `select` ব্যবহার করে একটিকে নির্বাচন করা হচ্ছে
    select {
    case msg1 := <-ch1:
        fmt.Println(msg1)
    case msg2 := <-ch2:
        fmt.Println(msg2)
    }
}

🔹 Output:

Bash
Message from channel 2

👉 এখানে, যেহেতু ch2 দ্রুত বার্তা পাঠিয়েছে, তাই select স্টেটমেন্ট ch2 এর case নির্বাচন করে।

2️⃣ একাধিক case

select স্টেটমেন্টে একাধিক চ্যানেল অপারেশন হ্যান্ডেল করা যায়। যদি কোনো চ্যানেল প্রস্তুত না থাকে, তবে select অপেক্ষা করবে যতক্ষণ না একটি চ্যানেল প্রস্তুত হয়।

🔹 উদাহরণ:

Go
package main

import (
    "fmt"
    "time"
)

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

    go func() {
        time.Sleep(1 * time.Second)
        ch1 <- "Data from ch1"
    }()
    
    go func() {
        time.Sleep(2 * time.Second)
        ch2 <- "Data from ch2"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-ch1:
            fmt.Println("Received:", msg1)
        case msg2 := <-ch2:
            fmt.Println("Received:", msg2)
        }
    }
}

🔹 Output:

Bash
Received: Data from ch1
Received: Data from ch2

👉 এখানে, select প্রথমে ch1 থেকে ডেটা গ্রহণ করে এবং পরে ch2 থেকে ডেটা গ্রহণ করে।

3️⃣ Default Case

আপনি select স্টেটমেন্টে একটি default case যুক্ত করতে পারেন, যা তখন কার্যকর হয় যখন কোনো চ্যানেল প্রস্তুত না থাকে। এই default case তৎক্ষণাৎ কার্যকর হবে যদি অন্য কোনো চ্যানেল অপারেশন প্রস্তুত না থাকে।

🔹 উদাহরণ:

Go
package main

import (
    "fmt"
    "time"
)

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

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

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

🔹 Output:

Bash
No message received, moving on...

👉 এখানে, default case কার্যকর হয়েছে কারণ চ্যানেল থেকে কোনো বার্তা এখনও পাওয়া যায়নি, তাই এটি তৎক্ষণাৎ কাজ শুরু করেছে।

4️⃣ Timeout ব্যবহার করে select

select স্টেটমেন্টটি টায়মআউট পরিচালনার জন্যও ব্যবহার করা যেতে পারে, যাতে একটি চ্যানেল অপারেশন অনির্দিষ্ট সময়ের জন্য অপেক্ষা না করে।

🔹 উদাহরণ:

Go
package main

import (
    "fmt"
    "time"
)

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

    go func() {
        time.Sleep(3 * time.Second)
        ch <- "Delayed message"
    }()

    select {
    case msg := <-ch:
        fmt.Println("Received:", msg)
    case <-time.After(2 * time.Second):
        fmt.Println("Timeout, no message received")
    }
}

🔹 Output:

Bash
Timeout, no message received

👉 এখানে, যেহেতু বার্তা ৩ সেকেন্ড পরে পাঠানো হচ্ছে, কিন্তু টাইমআউট ২ সেকেন্ডে সেট করা হয়েছে, তাই টাইমআউট case প্রথমে কার্যকর হয়।

সারসংক্ষেপ:

  • select statement Go-তে একাধিক চ্যানেল অপারেশন অপেক্ষা করতে এবং প্রথমে প্রস্তুত হওয়া অপারেশনটি নির্বাচন করতে ব্যবহৃত হয়।
  • একাধিক case হ্যান্ডেল করা যায়, একটি default case ব্যবহার করা যেতে পারে দ্রুত কার্যকর করার জন্য, এবং timeout এর মাধ্যমে অপেক্ষা করা হতে পারে।
  • এটি Go-তে concurrent goroutines এবং চ্যানেলগুলির মধ্যে কার্যকর যোগাযোগ এবং সমন্বয়ের জন্য একটি গুরুত্বপূর্ণ টুল।

©2025 Linux Bangla | Developed & Maintaind by Linux Bangla.