SoFunction
Updated on 2025-03-01

A brief discussion on golang channel types

1. What is the channel type

Channels in the Go language are a special type. The channel is like a conveyor belt or queue, always following the first-in-first-out rules to ensure the order in which data is sent and received. Each channel is a specific type of conduit, that is, when declaring a channel, it needs to specify the element type.

If goroutine is the execution body of the concurrent Go program, the channel is the connection between them. Channel is a communication mechanism that allows one goroutine to send a specific value to another goroutine.

2. Causes of channel generation

Although shared memory can be used for data exchange, there are different goroutines in shared memory that are prone to competitive problems. In order to ensure the correctness of data exchange, memory must be locked using mutexes, which inevitably leads to performance problems.

The concurrency model of Go is CSP (Communicating Sequential Processes), which advocates the realization of communication through communication rather than through shared memory.

3. Declare channel

grammar:

var variable chan element type

example:

var ch1 chan int   // Declare a channel that passes integersvar ch2 chan bool  // Declare a channel passing a booleanvar ch3 chan []int // Declare a passintSliced ​​channel   

4. Create a channel

grammar:

make(chan Element type, [Buffer size])  

Note: The declared channel needs to be initialized using the make function before it can be used. The buffer size of the channel is optional.

example:

ch4 := make(chan int, 3)
ch5 := make(chan bool)
ch6 := make(chan []int)   

5. Channel-related operations

1. Send value

Send a value to the channel.

example:

ch <- 10 // Bundle10Send tochmiddle   

2. Receive value

Receive values ​​from a channel.

example:

x := <- ch // Receive the value from ch and assign it to the variable x<-ch       // fromchReceived value,Ignore the results   

3. Close the channel

example:

close(ch)   

3.1 Note

The channel needs to be closed only when all data in the notification recipient has been sent. The channel can be recycled by the garbage collection mechanism. It is different from closing the file. It is necessary to close the file after the operation is finished, but closing the channel is not necessary.

3.2 Features

  • Sending values ​​to a closed channel will result in panic.
  • Receiving a closed channel will get the value until the channel is empty.
  • Performing a reception operation on a closed and without a value will result in a zero value of the corresponding type.
  • Close a closed channel will result in panic.

6. Channel type

1. No buffered channel

Unbuffered channels can only send values ​​when someone receives them. Just like the community where you live does not have a courier cabinet or collection point, the courier calls you and must deliver this item to you. Simply put, the unbuffered channel must be received before it can be sent.

grammar:

ch := make(chan type) 

example:

func recv(c chan int) {
    ret := <-c
    ("Received successfully", ret)
}
func main() {
    ch := make(chan int)
    go recv(ch) // Enable goroutine to receive values ​​from the channel    ch <- 10
    ("Send successfully")
}  

Analysis: The sending operation on the unbuffered channel will block until another goroutine performs the receive operation on the channel. The value can be successfully sent and the two goroutines will continue to execute. Instead, if the receiving operation is performed first, the receiving goroutine will block until another goroutine sends a value on that channel.

2. Buffered channel

As long as the capacity of the channel is greater than zero, the channel is a buffered channel, and the capacity of the channel represents the number of elements that can be stored in the channel. Just like the express cabinet in your community has only so many grids, and it can't be installed when the grid is full and it will be blocked. When someone takes away a courier, you can put one inside.

grammar:

ch := make(chan type, [cap]) 

example:

func main() {
    ch := make(chan int, 1) // Create a buffered channel with capacity of 1    ch <- 10
    ("Send successfully")
}   

7. One-way channel

Sometimes we pass the channel as a parameter between multiple task functions. Many times, when we use channels in different task functions, we will restrict it, such as limiting the channel to be sent or received in the function.

grammar:

chan<- int  is a channel that can only be sent, can be sent but cannot be received;
<-chan int  is a channel that can only be received, but cannot be sent.

example:

func counter(out chan<- int) {
    for i := 0; i < 100; i++ {
        out <- i
    }
    close(out)
}

func squarer(out chan<- int, in <-chan int) {
    for i := range in {
        out <- i * i
    }
    close(out)
}
func printer(in <-chan int) {
    for i := range in {
        (i)
    }
}

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    go counter(ch1)
    go squarer(ch2, ch1)
    printer(ch2)
}

Note: It is OK to convert a bidirectional channel to a one-way channel in function parameters and any assignment operations, but it is not the reverse.

8. Loop value from the channel

example:

// channel practicefunc main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    // Turn on goroutine to send the number from 0 to 100 to ch1    go func() {
        for i := 0; i &lt; 100; i++ {
            ch1 &lt;- i
        }
        close(ch1)
    }()
    // Turn on goroutine to receive the value from ch1 and send the square of the value to ch2    go func() {
        for {
            i, ok := &lt;-ch1 // After the channel is closed, the value is ok=false            if !ok {
                break
            }
            ch2 &lt;- i * i
        }
        close(ch2)
    }()
    //Receive value from ch2 in main goroutine    for i := range ch2 { // The for range loop will be exited after the channel is closed        (i)
    }
}   

Analysis: There are two ways to determine whether the channel is closed when receiving values. We usually use the for range method.

This is all about this article about the golang channel type. For more related golang channel type content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!