一、单向通道

单向channel变量的声明非常简单,如下:

var ch1 chan int       // ch1是一个正常的channel,是双向的

var ch2 chan<- float64 // ch2是单向channel,只用于写float64数据

var ch3 <-chan int     // ch3是单向channel,只用于读int数据

可以将 channel 隐式转换为单向队列,只收或只发,不能将单向 channel 转换为普通 channel:

    c := make(chan int, 3)

    var send chan<- int = c // send-only

    var recv <-chan int = c // receive-only

    send <- 1

    //<-send //invalid operation: <-send (receive from send-only type chan<- int)

    <-recv

    //recv <- 2 //invalid operation: recv <- 2 (send to receive-only type <-chan int)

    //不能将单向 channel 转换为普通 channel

    d1 := (chan int)(send) //cannot convert send (type chan<- int) to type chan int

    d2 := (chan int)(recv) //cannot convert recv (type <-chan int) to type chan int

package main

import (
"fmt"
)

//写入通道
func Product(c chan<- int) {
for i := 0; i < 5; i++ {
c <- i
}
//关闭通道
close(c)
}

//读取通道
func Customer(c <-chan int) {
//阻塞等待通道传输数据或关闭
for data := range c {
fmt.Println(data)
}
}

func main() {
c := make(chan int)
//创建协程
go Product(c)
Customer(c)
fmt.Println("done")
}

 二、生产者消费者模型

单向channel最典型的应用是“生产者消费者模型”

所谓“生产者消费者模型”: 某个模块(函数等)负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、协程、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。

单单抽象出生产者和消费者,还够不上是生产者/消费者模型。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据。大概的结构如下图:

Go语言 之单向channel及应用_数据

缓冲区的作用:

1、解耦

2、处理并发

3、缓存数据