当前位置:网站首页>Go language channel understanding and use

Go language channel understanding and use

2022-06-11 00:18:00 Game programming

First of all, I read a paragraph from a guide before I wanted to write this article , It is mainly a paragraph that is easy to be misunderstood , Here I directly attach his code . You can also look at some basic knowledge first :
Catalog


Basics

effect : Used to transfer information between processes
type : The channel is a reference type , Rules are similar to slices , need make
Define ways and actions :

var ch chan int// The last one identifies the element type passed by the channel 
make(chan  Element type , [ Buffer size ])ch <- n // Write n <- ch // read close(ch)// close 

Misunderstanding code

The core of the code is two threads and an unbuffered channel . Misunderstanding mainly occurs in the following basis notes ** After the channel is closed, the value can be taken ok=false**, For the unbuffered channel he set to exchange information , It can be right , But if there is a buffer channel , Is an obvious mistake . Below I attach a slightly modified code , The comparison between the two shows .

package main// Code 1 import (    "fmt"    //"time")func main() {    ch1 := make(chan int)    ch2 := make(chan int)    //  Turn on goroutine take 0~100 The number of is sent to ch1 in     go func() {        for i := 0; i < 100; i++ {            ch1 <- i        }        close(ch1)    }()    //  Turn on goroutine from ch1 Received value in , And send the square of the value to ch2 in     go func() {        for {            i, ok := <-ch1 // ** After the channel is closed, the value can be taken ok=false**            if !ok {                break            }            ch2 <- i * i        }        close(ch2)    }()    //  In the main goroutine In the from ch2 Print the received value in     for i := range ch2 { //  When the channel is closed, it exits for range loop         fmt.Println(i)    }}

This is a slightly modified code , You can see two changes , When overflowing, turn the channel 1 Replaced with buffered , Turn off the channel at one place 1 Time to i=50 When , Let's compare the execution results of the two :

Modify the code and compare the results

package mainimport (    "fmt"    //"time")func main() {    ch1 := make(chan int,100)// Changed to a buffered channel     ch2 := make(chan int)    //  Turn on goroutine take 0~100 The number of is sent to ch1 in     go func() {        for i := 0; i < 100; i++ {            ch1 <- i        }    }()    //  Turn on goroutine from ch1 Received value in , And send the square of the value to ch2 in     go func() {        for {            i, ok := <-ch1 //  After the channel is closed, the value can be taken ok=false            if !ok {                break            }            // Amendment             if i == 50{                close(ch1)            }            ch2 <- i * i        }        close(ch2)    }()    //  In the main goroutine In the from ch2 Print the received value in     for i := range ch2 { //  When the channel is closed, it exits for range loop         fmt.Println(i)    }}
Go Language Channel Understand the use of - The first 1 Zhang
Go Language Channel Understand the use of - The first 2 Zhang

You can see , Although the channel was closed in advance , But because there is a buffer , Characters are normally extracted , because
i, ok := <-ch1 As long as there is a value in the channel, it will return ok. Data cannot be added after closing , But the channel value is normal , Only when the element is fetched will it return false. In fact, the reason why it works is that there is no buffer channel , The receiving channel will be blocked until the sender transmits the value , There are no elements in the channel . So if you don't receive , You cannot add values to an unbuffered channel .

One way passage

Sometimes we will pass channels as parameters between multiple task functions , Many times we use channels in different task functions to restrict it , For example, the channel can only be sent or received in the function .
Go The language provides a one-way channel to handle this situation :
You can convert a two-way channel into a one-way channel in function parameters and any assignment operation .

package mainimport "fmt"// Write channel 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)}// Read channel func printer(in <-chan int) {    for i := range in {        fmt.Println(i)    }}func main() {    ch1 := make(chan int)    ch2 := make(chan int)    go counter(ch1)    go squarer(ch2, ch1)    printer(ch2)}

author :Chinatesila

Game programming , A game development favorite ~

If the picture is not displayed for a long time , Please use Chrome Kernel browser .

原网站

版权声明
本文为[Game programming]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206102248257510.html