After initialization, the channel is ready to transmit data. It is in an open state and we can interact with it until it is closed using the built-in close()
function:
package main
import "fmt"
func main() {
chann := make(chan int, 3)
chann<- 2023
chann<- 2024
close(chann)
// chann<- 2025 // Error - the channel is already closed
fmt.Println(<-chann) // 2023
fmt.Println(<-chann) // 2024
fmt.Println(<-chann) // 0
}
Once the channel is closed, we will not be able to send new data to it. If we try to do this, we will get an error. However, we can retrieve previously added data. But if we try to get data from a channel that is not there, we will get the default value.
For example, in the example above, two values are added to the channel. If we try to get a third value that is not in the channel, we will get the default value the number 0.
To avoid running into a problem when the channel is already closed, we can check the status of the channel. In particular, we can get two values from the channel:
st, isActive:= <-chann
The first value st is the actual data from the channel, and isActive represents a boolean value that is true if the channel is open and we can successfully read data from it. For example, we can check the state of a channel using a conditional construct:
package main
import "fmt"
func main() {
chann:= make(chan int, 3)
chann<- 2023
chann<- 2024
close(chann) // Close the channel
for i := 0; i < cap(chann); i++ {
if st, isActive:= <-chann; isActive{
fmt.Println(st)
} else {
fmt.Println("Channel is closed!")
}
}
}
And we get:
2023
2024
Channel is closed!