代码例子是gobyexample里的通道关闭演示代码:
package main
import "fmt"
func main() {
jobs := make(chan int, 5)
done := make(chan bool)
go func() {
for {
j, more := <-jobs
if more {
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job", j)
}
close(jobs)
fmt.Println("sent all jobs")
<-done
}
其中j, more := <-jobs挺久
这是一个通道的读取操作,将通道`jobs`中的数据读取出来并分别赋值给`j`和`more`。通道的读取操作使用尖括号`<-`,通道名放在尖括号左侧,读取的数据则放在尖括号右侧。如果通道已经被关闭或者没有数据可读,该操作会阻塞等待。 具体来说,`jobs`是一个通道变量,对其进行读取时会阻塞程序,直到有新的数据写入这个通道。读取操作会将通道中的数据读取出来,并将其赋值给`j`。如果通道中还有更多的数据,则`more`的值为`true`,否则为`false`。如果通道已经被关闭,那么读取操作将不再阻塞程序,并且返回通道的默认值。在这种情况下,`more`通常会被设置为`false`。如果需要处理每个数据,则可以将读取操作放在for循环中
运行结果如下:
$ go run closing-channels.go
sent job 1
received job 1
sent job 2
received job 2
sent job 3
received job 3
sent all jobs
received all jobs
<-done
此操作是从通道`done`中读取数据,但是此时程序不需要将读取到的数据保存下来。该操作也被称为通道的阻塞操作,如果通道中没有数据可读,则该操作将一直阻塞程序,直到有新的数据可读。在这里,程序不需要读取到数据,因为在主函数中读取`done`通道的操作只是为了等待所有的任务结束。 当协程完成任务时,它将数据发送到`done`通道。在主函数中,每次从通道中读取一个数据,该操作将会阻塞程序,直到所有协程均已完成任务并将数据发送到`done`通道。此时,程序将继续执行下去,完成所有任务的处理。