Buffered Channel in Golang

Buffered channels are also created using the function make(), only the channel capacity is passed as the second argument to the function. If the channel is empty, then the receiver waits until at least one element appears in the channel.

When sending data, the sender goroutine waits until there is room in the channel for one more element and sends the element only when space is freed for it in the channel.

package main
import "fmt"
 
func main() {
     
    iChan:= make(chan int, 4) 
    iChan<- 2022
    iChan<- 2023
    iChan<- 2024
    iChan<- 2025
    fmt.Println(<-iChan) 
    fmt.Println(<-iChan)    
    fmt.Println(<-iChan)    
   fmt.Println(<-iChan) 
}

The output will be like this:

2022
2023
2024
2025

In this case, the sender and recipient of the data are the main function. It creates a channel of four elements and sends four int values sequentially.

At the same time, in this case, there must be a correspondence between the amount of data sent and received. If the main function simultaneously sends more values than the channel can accommodate, the function will block:

package main
import "fmt"
 
func main() {
     
    iChan:= make(chan int, 4) 
    iChan<- 2022
    iChan<- 2023
    iChan<- 2024
    iChan<- 2025
    iChan<- 2026
  
    fmt.Println(<-iChan)
    fmt.Println("Done!)
}

Using the built-in functions cap() and len() you can get the capacity and number of elements in the channel, respectively:

package main
import "fmt"
 
func main() {
     
    iChan := make(chan int, 4) 
    iChan <- 2024
     
    fmt.Println(cap(iChan))     // 4
    fmt.Println(len(iChan))     // 1
     
    fmt.Println(<-iChan)
}

The output will be like this:

4
1
2024

The channel can be the return value of a function. However, you should be careful about writing and reading operations on the returned channel. For example:

package main

import "fmt"

func main() {
	fmt.Println("Starting!")
	// Create a channel and retrieve data from it
	fmt.Println(<-funcChan(2024)) // 2024
	fmt.Println("Done!")
}

func funcChan(n int) chan int {
	chann := make(chan int) // Creating a channel
	chann <- n              //Send data to the channel
	return chann            // Returning the Channel
}

The funcChan function returns the channel. However, when performing the operation chann <- n, we will encounter blocking as we wait for data to be received from the channel. Therefore the following expression return chwill not be executed.

And if you still need to define a function that returns a channel, then all read-write operations to the channel should be placed in a separate goroutine:

package main
import "fmt"
  
func main() {
    fmt.Println("Starting!")
     // Create a channel and retrieve data from it
    fmt.Println(<-funcChan(2024)) // 2024
    fmt.Println("Done!")
}
func funcChan(n int) chan int{
    chann := make(chan int)    // Creating a channel
    go func(){
        chann <- n      // Send data to the channel
    }()             // Starting the goroutine
    return chann // Returning the Channel
}

And will get this:

Starting!
2024
Done!