channel 必须用 make 初始化,声明 var ch chan int 后未 make 会导致读写 panic;正确写法是 ch := make(chan int) 或 ch := make(chan int, 10);传参需传已初始化实例;向已关闭 channel 发送数据会 panic。

channel 必须 make 初始化,不能直接声明后使用
声明 chan int 类型变量但未用 make 创建底层结构,会导致 panic:「send on nil channel」或「receive from nil channel」。Go 不会自动分配缓冲区或调度器关联逻辑。
-
var ch chan int→ch是 nil,任何读写都阻塞并 panic - 正确写法是
ch := make(chan int)(无缓冲)或ch := make(chan int, 10)(带缓冲) - 函数参数中若接收
chan int,调用方必须传入已make的实例,不能传零值
向已关闭的 channel 发送数据会 panic
关闭 channel 后继续 ch 会触发运行时 panic:「send on closed channel」。但接收操作仍安全:可读完剩余数据,之后持续返回零值 + <code>false(ok 为 false)。
- 只应由 sender 关闭 channel,receiver 不应 close
- 多个 goroutine 同时发送时,需确保仅一个负责
close(ch),常见做法是用sync.Once或由主发送协程统一关闭 - 判断是否关闭:用
val, ok := ,<code>ok == false表示已关闭且无数据
无缓冲 channel 的收发必须配对,否则永久阻塞
make(chan int) 创建的是同步 channel,发送和接收必须在两个 goroutine 中同时就绪,否则任一端都会阻塞。这是最易踩的坑——误当成「队列」直接用在单 goroutine 里。
- 错误示例:
ch := make(chan int); ch → 死锁(deadlock) - 正确方式:至少一个操作放在 goroutine 中,如
go func() { ch - 若需单 goroutine 内非阻塞通信,改用带缓冲 channel(如
make(chan int, 1))或加select配default
range 遍历 channel 会在关闭后自动退出,但无法区分「空 channel」和「刚关闭」
for v := range ch 是安全遍历方式,它隐含等待、接收、判断关闭三步,关闭后循环自然结束。但注意它不适用于「可能永远不关闭」的 channel,会导致 goroutine 泄漏。
立即学习“go语言免费学习笔记(深入)”;
- 如果 sender 不关 channel,
range永远卡在接收,goroutine 无法退出 - 不要在 range 循环里重复 close channel,会 panic
- 若需提前退出(如超时),必须用
select+context控制,不能依赖 range 自身逻辑
实际写并发逻辑时,channel 的生命周期管理比语法本身更关键:谁创建、谁关闭、谁读、谁写,这些职责一旦错位,问题往往出现在运行时而非编译期。










