go中的管道
1管道三种类型区分- 双向管道 chan T 可读可写- 只读管道 -chan T 只读不写、不可close- 只写管道 chan- T 只写不读、可closepackage mainimport fmtfunc main() {// 双向管道ch : make(chan int, 1)// 转为只读var readCh -chan int ch// 转为只写var writeCh chan- int chwriteCh - 10fmt.Println(-readCh)close(writeCh)}2单向管道不能直接make创建只能由双向管道转换而来直接创建单向管道编译报错package mainfunc main() {// 错误写法直接创建单向管道// ch : make(chan- int)// 正确写法先双向再转换ch : make(chan int)var writeCh chan- int ch_ writeCh}3转换规则双向可转单向单向不可转回双向package mainfunc main() {ch : make(chan int)var readCh -chan int ch// 错误单向转双向// var ch2 chan int readCh_ readCh}知识点4只读管道禁止写、禁止closepackage mainfunc main() {ch : make(chan int, 1)var readCh -chan int ch// 以下两行都会编译报错// readCh - 20// close(readCh)}5只写管道禁止读、允许closepackage mainfunc main() {ch : make(chan int)var writeCh chan- int chwriteCh - 30close(writeCh)// 错误只写管道不能读// fmt.Println(-writeCh)}6单向管道基础生产者消费者模型函数参数约束单向管道划分读写职责package mainimport fmt// 生产者只写管道func producer(ch chan- int) {ch - 100close(ch)}// 消费者只读管道func consumer(ch -chan int) {fmt.Println(-ch)}func main() {ch : make(chan int)go producer(ch)consumer(ch)}7只读管道与select联用只能走读分支package mainimport fmtfunc recv(ch -chan int) {select {case v : -ch:fmt.Println(读到, v)// 写分支编译报错// case ch - 50:}}func main() {ch : make(chan int, 1)ch - 50recv(ch)}8只写管道与select联用只能走写分支package mainimport fmtfunc send(ch chan- int) {select {case ch - 60:fmt.Println(写入成功)// 读分支编译报错// case v : -ch:}}func main() {ch : make(chan int, 1)send(ch)fmt.Println(-ch)}单向管道1. 定义单向管道是对双向Channel的方向限制仅支持读或写其中一种操作核心作用是约束权限、提升代码安全性与可读性。2. 类型与语法- 只读Channel -chan T 仅可读取数据不可写入- 只写Channel chan- T 仅可写入数据不可读取3. 核心特性- 无法直接创建只能由双向Channel chan T 转换而来- 单向→双向的反向转换不合法编译报错- 底层仍为原双向Channel仅做语法权限限制无额外运行开销4. 关键操作限制- close() 仅能在写端双向/只写Channel调用只读Channel无法执行- 只读Channel可执行 range 遍历、读取、判断关闭只写Channel可执行写入、 close()5. 核心使用场景- 函数参数权限约束生产者用 chan- T 、消费者用 -chan T 明确接口契约- 避免协程误操作防止越权读写导致的并发逻辑混乱- 大型项目代码规范清晰区分数据生产/消费角色6. 常见易错点- 直接创建单向Channel会编译报错- 只读Channel执行写入、只写Channel执行读取编译报错- 只读Channel调用 close() 会编译报错7. 本质Go编译器的语法糖编译期做类型检查不改变Channel底层结构