Iterate over Channel in Golang

Learn via video courses
Topics Covered

Overview

A channel is a Go channel mechanism that enables concurrent communication between goroutines. Data may be sent and received between goroutines using channels, enabling secure and effective communication. To iterate over a channel, you can use the range keyword for a loop. This will repeatedly receive values from the channel until it is closed.

Using the Range Function in Golang to Iterate over the Channels

The "range" keyword in Go is used to iterate over the elements of a collection, such as an array, slice, map, or channel. It allows you to access each element in the collection one at a time, and is typically used in conjunction with a "for" loop.

range is also useful for iterating over the channel. It will repeat for each item that is sent on the channel. Both buffered and unbuffered channels can be iterated, but both need to be closed before iterating over them. For Example:

Output for the above code:

Run the code!

Explanation of the above code:

  • In the above example, we created a buffered channel called queue with a capacity of 2.
  • It then sends the strings one and two to the channel using the <- operator. The channel is then closed using the close function.
  • Finally, the code uses a for range loop to iterate over the elements in the channel and print them to the console using the fmt.Println function.
  • The code will print one and two to the console and exit as the channel is closed after adding two elements, which makes the range loop stop.

Close Golang Channel

Close() makes it possible to inform channel users that nothing further will be communicated on that channel if the close is added there. For a more detailed understanding let's see an example. Without close:

Output for the above code:

Run the code!

Explanation of the code:

  • We received the values of both the sending and receiving channels when iterating through the channels in Golang, but we also encountered a deadlock.
  • This happens because there is no end constraint for the loop and data can exit the channel at any moment, deadlock develops because the loop is unable to determine when the Golang channel terminates.
  • The solution to handle this is to close the channel so that it can tell the loop to stop iterating as the channel is closed and no deadlock will occur. With close:

Output for the above code:

Run the code!

Explanation of the above code:

  • In the above code, we just added the close() which is helping a loop about the closing of the channel and thus the loop also breaks.
  • One thing we should consider is that after the close statement, there should not be added values due to if any value is passed after the close, it will start panic. Another Example:

Output for the code:

Run the code!

Explanation of the code:

  • In the main function we created an unbuffered channel ch of type int using the make(chan int) function.
  • A goroutine is then launched using the go keyword and an anonymous function is passed to it. The function runs a loop that sends the values of i from 0 to 4 to channel ch. After the loop, the channel is closed using the close(ch) function.
  • The main function then ranges over the channel, receiving values from it and printing them to the console using the fmt.Println(v) function.
  • When the channel is closed and there are no more values to receive, the range loop will exit and the program will terminate.
  • So in short the program creates an unbuffered channel, launches a goroutine that sends 5 integers to the channel and closes it, main function ranges over the channel and prints the integers.

Iteration over an Unbuffered Channel

The range keyword can be used on the unbuffered channel.

Code Implementation

Output for the above code:

Run the code!

Explanation of the code:

  • In the above code, we created an unbuffered channel called ch of type int using the make function. An unbuffered channel means that the channel will block until there is a receiver ready to receive the data.
  • It then starts a goroutine that sends the integers 1, 2, and 3 to the channel and then closes it.
  • Finally, the code uses a for range loop to iterate over the channel, where it repeatedly receives data from the channel until it is closed. The received data is then printed to the console using the fmt.Println function.
  • Each iteration of the loop assigns the next value received from the channel to the variable element and prints it to the console.
  • Since the channel is closed after sending all the data, the loop will stop iterating and the program will exit.

Iteration over the Buffered Channel

In Go, you can use the range function to iterate over a buffered channel and receive values from it until the channel is closed.

Code Implementation

Output for the above code:

Run the code!

Explanation of the code:

  • In this example, the program creates a buffered channel ch with a capacity of 3 and sends 3 integers to the channel. After sending the integers, the channel is closed using the close(ch) function.
  • The program then uses a for loop with the range keyword to iterate over the channel. The range keyword receives values from the channel and assigns them to the v variable, which is then printed to the console using the fmt.Println(v) function.
  • The iteration will continue until the channel is closed, and all the values sent to the channel are received and printed.
  • Note that after closing the channel, it will not accept any new value, and trying to send value to a closed channel will cause a panic.

Conclusion

  • In this article, we have seen how to iterate over channels in Golang using the range keyword. We also saw how to iterate over both buffered and unbuffered channels. Additionally, we have also seen the importance of closing channels in Go and how it can prevent the deadlock when iterating over channels.
  • It's important to keep in mind that closing a channel does not remove the values from the channel, it only signals to the receivers that no more values will be sent on the channel. This means that after a channel is closed, it's still possible to receive the values that were already sent on the channel, but no new values can be sent.
  • It's also important to note that closing a channel multiple times can cause panic, so it's good practice to only close a channel once or to use a boolean flag to check if the channel is already closed before closing it.
  • At last, iterating over channels in Go can be a powerful tool for concurrent programming, but it's important to use it correctly and be aware of the potential pitfalls.