AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
## 什么是channel 如果说goroutine是Go语言程序的并发体的话,那么channels则是它们之间的通信机制。一个channel是一个通信机制,**它可以让一个goroutine通过它给另一个goroutine发送值信息**。每个channel都有一个特殊的类型,也就是channels可发送数据的类型。一个可以发送int类型数据的channel一般写为chan int。 ## channel是引用类型 和map类似,channel也对应一个make创建的底层数据结构的引用。当我们复制一个channel或用于函数参数传递时,我们只是拷贝了一个channel引用,因此调用者和被调用者将引用同一个channel对象。和其它的引用类型一样,channel的零值也是nil。 ## channel比较 两个相同类型的channel可以使用==运算符比较。如果两个channel引用的是相同的对象,那么比较的结果为真。一个channel也可以和nil进行比较。 ## channel操作符 一个channel有发送和接受两个主要操作,都是通信行为。一个发送语句将一个值从一个goroutine通过channel发送到另一个执行接收操作的goroutine。发送和接收两个操作都使用`<-`运算符。在发送语句中,`<-`运算符分割channel和要发送的值。在接收语句中,`<-`运算符写在channel对象之前。一个不使用接收结果的接收操作也是合法的。 ``` <- ch1 //不使用channel中的值,是合法的 ``` ## 基于channel的两个重要方面 1. 基于channels发送消息有两个重要方面。首先每个消息都有一个值,但是有时候通讯的事实和发生的时刻也同样重要。当我们更希望强调通讯发生的时刻时,我们将它称为**消息事件**。 2. 有些消息事件并不携带额外的信息,它仅仅是用作两个goroutine之间的同步,这时候我们可以用`struct{}`空结构体作为channels元素的类型,虽然也可以使用bool或int类型实现同样的功能,`done <- 1`语句也比`done <- struct{}{}`更短。 ## close close函数用于关闭channel,往已经关闭的channel中发送数据会引起panic. 但是从已经关闭的channel中接受数据不会产生panic,而是会接收到已经发送的数据,如果没有数据,就会接收到零值. 试图重复关闭一个channel将导致panic异常,试图关闭一个nil值的channel也将导致panic异常。关闭一个channels还会触发一个广播机制. ## range 在使用range来接收channel的值的时候,如果没有close掉channel的话,range是不会自己跳出的. ~~~ ch := make(chan int) go func() { for i := 0; i < 5; i++ { ch <- i time.Sleep(time.Second) } close(ch) }() for { x := <-ch fmt.Println(x) } //for { // x, ok := <-ch // if !ok { // break // } // fmt.Println(x) //} ~~~ 结果: ``` 0 1 2 3 4 0 0 0 0 ... ```