chan通道、信道

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!
Build by Loppo 0.6.15