通道类型
通道(Channel)是Go语言中一种非常独特的数据结构。 它可用于在不同Goroutine之间传递类型化的数据,并且是并发安全的。
通道类型的表示方法很简单,仅由两部分组成
chan T
在这个类型字面量中,左边是代表通道类型的关键字chan,而右边则是一个可变的部分。
即代表该通道类型允许传递的数据的类型(或称通道的元素类型)。
这两部分之间需要以空格分隔。
与其它的数据类型不同,我们无法表示一个通道类型的值。
因此,我们也无法用字面量来为通道类型的变量赋值。
只能通过调用内建函数make(chan T, len)来达到目的。 第一个参数: 类型的字面量(比如chan int), 第二个参数:值的长度。 初始化一个长度为5且元素类型为int的通道值,则需要这样写: make(chan int, 5)
通道值的长度应该被称为其缓存的尺寸。
换句话说,它代表着通道值中可以暂存的数据的个数。
暂存在通道值中的数据是 先进先出 的,
声明一个通道类型的变量,并为其赋值: ch1 := make(chan string, 5)
<-
接收操作符<- : 向通道值发送数据。
当然,也可以使用它从通道值接收数据。
向通道ch1发送字符串"value1",
ch1 <- "value1"
接收到的字符串赋给一个变量:
value := <- ch1
针对字典值的索引表达式一样,针对通道值的接收操作也可以有第二个结果值:
value, ok := <- ch1
对通道值的重复关闭会引发运行时异常。这会使程序崩溃。所以一定要避免这种情况的发生。
1、在通道值有效的前提下,针对它的发送操作会在通道值已满(其中缓存的数据的个数已等于它的长度)时被阻塞。
2、而向一个已被关闭的通道值发送数据会引发运行时崩溃。
3、针对有效通道值的接收操作会在它已空(其中没有缓存任何数据)时被阻塞。
与切片和字典类型相同,通道类型属于引用类型。它的零值即为nil
缓冲通道中可以缓存N个数据。我们在初始化一个通道值的时候必须指定这个N。
非缓冲通道
非缓冲通道不会缓存任何数据。 发送方在向通道值发送数据的时候会立即被阻塞,直到有某一个接收方已从该通道值中接收了这条数据。 非缓冲的通道值的初始化方法如下:给予make函数的第二个参数值是0。 make(chan int, 0)
数据在通道中的传输方向为依据来划分通道。
默认情况下,通道都是双向的,即双向通道。
如果数据只能在通道中单向传输,那么该通道就被称作单向通道。
我们在初始化一个通道值的时候不能指定它为单向。
但是,在编写类型声明的时候,我们却是可以这样做的。 type Receiver <-chan int 类型Receiver代表了一个只可从中 接收 数据的 单向通道类型。 这样的通道也被称为 接收通道。 在关键字chan左边的接收操作符<-形象地表示出了数据的流向
声明一个发送通道类型,那么应该这样: type Sender chan<- int