章节

10.3 channel

本篇学习 channel 的创建、发送、接收与关闭,并知道何时用 channel 在 goroutine 之间传递数据和同步。

channel

概念说明

channel 是 goroutine 之间传递数据的管道。
它既能传值,也能同步执行时机。

默认创建的是无缓冲 channel。
无缓冲 channel 的特点是:发送和接收必须同时准备好,否则其中一方就会等待。

语法/规则

  1. 使用 make(chan T) 创建 channel。
  2. 使用 ch <- value 向 channel 发送数据。
  3. 使用 value := <-ch 从 channel 接收数据。
  4. 发送方可以使用 close(ch) 关闭 channel,表示后面不会再发送数据。
  5. 使用 for value := range ch 可以持续读取,直到 channel 被关闭。
  6. 不要向已经关闭的 channel 发送数据,会触发 panic。

语法模板

1
2
3
4
5
6
7
ch := make(chan int)

go func() {
	ch <- 1
}()

value := <-ch

channel 传递数据示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

func main() {
	numbers := make(chan int) // 创建一个 int 类型的 channel,用来传递数字

	go func() {
		for i := 1; i <= 3; i++ {
			numbers <- i // 把 i 发送到 channel 中
		}
		close(numbers) // 发送完成后关闭 channel,告诉接收方“后面没有数据了”
	}()

	for number := range numbers { // 持续接收数据,直到 numbers 被关闭
		fmt.Println(number)
	}
}

输出结果:

1
2
3
1
2
3

怎么理解这个示例

  1. 一个 goroutine 发送数据,主 goroutine 负责接收并打印。
  2. for number := range numbers 会一直读,直到 numbers 被关闭。
  3. 所以这个例子既展示了“怎么传值”,也展示了“怎么通知接收方数据发完了”。

什么时候会用到 channel

当多个 goroutine 之间需要传数据或配合同步时,就会用到 channel。
下面两个示例分别演示了“连续发送一组数据”和“把计算结果交回主 goroutine”这两种常见用法。

场景:后台计算结果后,把结果交给主 goroutine

goroutine 不能像普通函数那样直接把返回值交回调用位置。
这时可以让后台 goroutine 通过 channel 把结果送回来:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package main

import "fmt"

func sum(a int, b int, resultCh chan int) {
	result := a + b
	resultCh <- result // 计算完成后,把结果发送给 channel
}

func main() {
	resultCh := make(chan int) // 创建一个 channel,用来接收结果

	go sum(10, 20, resultCh) // 启动 goroutine 进行计算

	result := <-resultCh // 等待接收结果;结果没来之前,这里会阻塞
	fmt.Println("result:", result)
}

输出结果:

1
result: 30

这个场景说明了什么

  1. go sum(10, 20, resultCh) 在后台计算结果。
  2. result := <-resultCh 会等待结果到来,而不是靠 time.Sleep 猜时间。
  3. 这就是 channel 的常见用法:一个 goroutine 算,一个 goroutine 收。

常见错误

  1. 只有发送没有接收,或只有接收没有发送,导致程序死锁。
  2. 接收方关闭 channel,容易让发送方继续发送时 panic;通常由发送方关闭。
  3. 误以为关闭 channel 是必须的,实际只有接收方需要判断结束时才需要关闭。
  4. 向已经关闭的 channel 发送数据,会触发 send on closed channel
本文禁止转载
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
最近构建时间:2026-04-17 19:07:48 CST
载入天数...载入时分秒...
发表了 1 篇文章 · 发表了 152 篇笔记 · 总计 18 万 0 千字