Welcome To Golang By Example

Select statement with a nil channel in Go (Golang)

Table of Contents

Overview

Send or receive operation on nil channel blocks forever. Hence a use case of having a nil channel in the select statement is to disable that case statement after the the send or receive operation is completed on that case statement. The channel then can simply be set to nil. That case statement will be  ignored when the select statement is executed again and receive or send operation will be e waited on another case statement. So it is meant to ignore that case statement and execute the other case statement

Code

package main

import (
    "fmt"
    "time"
)

func main() {
    news := make(chan string)
    go newsFeed(news)
    printAllNews(news)
}

func printAllNews(news chan string) {
    for {
        select {
        case n := <-news:
            fmt.Println(n)
            news = nil
        case <-time.After(time.Second * 1):
            fmt.Println("Timeout: News feed finished")
            return
        }
    }
}

func newsFeed(ch chan string) {
    for i := 0; i < 2; i++ {
        time.Sleep(time.Millisecond * 400)
        ch <- fmt.Sprintf("News: %d", i+1)
    }
}

Output

News: 1
Timeout: News feed finished

In the above program, we have created a channel named news  which will hold data of string type. Then we pass this channel to the newsfeed function which is pushing the news feed to this channel . In the select statement, we are receiving the news feed from the news channel. This select statement is inside an infinite for loop  so the select statement will be executed multiple times until we  exit out of for loop . We also have time.After with a duration for 1 second as one of the case statements. So this set up will receive all the news from the news channel for  1  second and then exit. 

After we receive the first news, we disabled the case statement by setting the news channel to nil.

case n := <-news:
   fmt.Println(n)
   news = nil

Hence we only received the first news and after that, it times out.  This is the use case of nil channel in the select statement. If we remove the below line

news = nil

then we will receive all the news in the ouput i.e, output will be

News: 1
News: 2
Timeout: News feed finished