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!