chan是什么 #
通道(channel)是用来传递数据的一种数据结构,又叫信道
用途:用于两个 goroutine 之间传递一个指定类型的值,启到同步运行和通讯的作用。
又叫连接多个协程的管道
chan变量定义 #
1.无缓冲通道
变量名 := make(chan 类型)
示例:e := make(chan string)
l := len(e)
c := cap(e)
无缓冲通道的len和cap值均为0
在读无缓冲通道的内容时,是阻塞状态,只到读取到内容为止。
2.有缓冲通道
变量名 := make(chan 类型, 缓冲长度)
示例:f := make(chan string, 10)
l := len(f)
c := cap(f)
有缓冲通道,len的值为未读取的个数,cap值为通道的容量即缓冲长度
chan通道操作 #
操作符: <- 用于指定通道的方向,发送或接收,把箭头右边的数据给箭头左边
如果未指定方向,则为双向通道
向通道写消息: 通道变量 <- "要写入的内容"或变量
示例: ch <- "你好"
从通道读消息: 普通变量名 := <-通道变量
示例:v := <-ch
从 ch通道 接收数据并赋值给v变量
示例2:v, ok := <-ch
go提供关闭通道方法:func close(c chan<- Type)
示例: close(通道变量)
chan示例1 #
package main
import "fmt"
func main() {
//定义通道变量,值类型为字符串
messages := make(chan string)
go func() {
//向通道发送消息
messages <- "你好"
}()
//阻塞、从通道取消息
msg := <-messages
//打印取到的消息
fmt.Println(msg)
}
通道方向示例 #
package main
import "fmt"
//只写通道
func ping(a chan<- string, msg string) {
a <- msg
}
//第1个参数只读通道,第2个参数只写通道
func pong(a <-chan string, b chan<- string) {
msg := <-a //从a通道读消息
b <- msg //把消息写给b通道
}
func main() {
//定义有缓冲通道
a := make(chan string, 1)
b := make(chan string, 1)
ping(a, "向通道写入消息message")
pong(a, b) //把a的消息读出,并写给b通道
fmt.Println(<-b) //获取b通道值
}
以上代码打印:向通道写入消息message
遍历通道 #
package main
import "fmt"
func main() {
//定义通道
queue := make(chan string, 2)
//向通道写消息
queue <- "one"
queue <- "two"
//关闭通道
close(queue)
//遍历通道
for elem := range queue {
fmt.Println(elem)
}
fmt.Println("finish")
}
以上代码打印:
one
two
finish
备注:在遍历通道前要关闭通道,否则如下报错
fatal error: all goroutines are asleep - deadlock!