谈谈go中的channel
在golang中channel用于goroutine之间的通信。
channel的定义
channel是引用类型,需要使用make来创建channel:make(chan Type, [buffer])
make对于channel接收两个参数,第一个是通道的类型,第二个是个可选参数代表通道缓冲区的大小(省略代表无缓冲)。
make(chan int) // 无缓冲
make(chan int, 2) // 带有两个缓冲的通道
channel的操作
- 向channel中放入元素
-
使用
<-
符号指向channel来将元素放入channel中 -
注意向通道中传值必须要求该通道还有容量(缓冲),而且通道不能关闭
-
对于无缓冲的或者缓冲已经满了的channel不可以轻易的传入值,必须要有goroutine同时在取元素才可以放入
-
向一个有缓冲,非满的channel传值
c := make(chan int, 1) // 定义一个带有一个缓冲的通道
c <- 1 // 向通道中传入一个1,正常
- 向一个有缓冲,满的channel传值
c := make(chan int, 1) // 定义一个带有一个缓冲的通道
c <- 1 // 向通道中传入一个值,这个值传入后填满了该通道
c <- 2 // 再向通道中传入一个值,报错
- 向一个无缓冲,的channel传值
c := make(chan int) // 定义一个无缓冲通道
c <- 1 // 向无缓冲通道传值,报错
- 从channel中取出元素
- 我们可以使用<-符号指向变量来将channel中的元素放变量中。此时可以接收两个值一个数值一个状态
- 可以通过range取值
- 注意从通道中取值必须要求该通道还有值
- 对于无缓冲的或者缓冲已经空了的channel不可以轻易的取出值,必须要同时在放元素才可以取出
- 可以向已经关闭的通道取值
c := make(chan int, 1)
c <- 1
a, ok := <-c
fmt.Println(a, ok) // 输出 1 true
///
c := make(chan int, 1)
close(c)
a, ok := <-c
fmt.Println(a, ok) // 输出 0 false
///
for {
v, ok := <- c
if !ok {
break
}
fmt<