channel(3) 一 基本定义
1.channel概念:
类似管道pipe
先进先出
线程安全,多个goroutine同时访问,不需要加锁
channel是有类型的,整数类型的channel只能存放整数类型的数据
2.channel声明
var 变量名 chan 类型
var test chan int
var test chan string
var test chan map[string]string
var test chan stu
var test chan *stu
3.channel类似于map,slice必须进行初始化
var test chan int
test = make(chan int,100) //在这里如果容量为0,会是什么结果呢?
4.channel接收数据和读取数据
intchan <-10 //把数据发送到管道中
result := <- intchan //从channel中读取数据,并赋值给result
接上面的疑问,如果容量为0,会是什么情况呢?还有一些问题来一一验证
没有初始化的情况:(报错 nil chan)
1 2 3 4 5 6 7 8 9 | import ( "fmt" ) func main() { var c chan int c <- 10 result:= <- c fmt.Println(result) //goroutine 1 [chan send (nil chan)]: } |
初始化后,容量 为0:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import ( "fmt" ) func main() { var c chan int c = make( chan int,0) c <- 10 result:= <- c fmt.Println(result) /* fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan send]: main.main() c:/goclass/src/day8goroutine/channel/main.go:9 +0x60 exit status 2 */ } |
还是报错,不太明显,我们换一种方法来测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import ( "fmt" "time" ) func main() { var c chan int c = make( chan int,0) go func (){ //开启一个goroutine fmt.Println( "start input to the channel" ) c <- 10 fmt.Println( "end input to the channel" ) }() time.Sleep(time.Second*100) result:= <- c fmt.Println(result) } //运行结果,会立马输出“start input to the channel” 这一行,然后等待100s后,会输入result结果10。因为容量为0的话,指的是channel没有缓存容量 ,就是不能够缓存任何数据,如果容量改为1的话,会立马输出start和end两句话。 |
5.channel 权限控制
var intchan chan <- int //intchan只可接收int类型数据
var intchan <- chan int //只可以从intchan中读取数据
var intchan chan int //即可以接收也可也读取数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package main import ( "fmt" "sync" ) var waitgroup sync.WaitGroup func SendDate(c chan <- string){ //往chan中写入数据,这个类型是只写的 c <- "beijing" c <- "shanghai" c <- "guangzhou" c <- "shenzhen" close(c) //写完数据关闭channel waitgroup.Done() } func GetDate(c <- chan string){ //读取chan中的数据,这个类型是只读的 for { input,ok :=<-c //检查channel 是否关闭 if !ok{ fmt.Println( "the chan is closed" ) break } fmt.Println(input) } waitgroup.Done() } func main() { c := make( chan string) waitgroup.Add(2) go SendDate(c) go GetDate(c) waitgroup.Wait() //等待所有的goroutine执行完成 } |
上面的代码中有权限的控制,goroutine和chan相结合。还有一个检查chan是否关闭
input,ok := <-c
遍历chan中的元素:
for input := range c{
fmt.Println(input)
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!