枫枫知道个人博客
首页
新闻
心情
关于
文章搜索
网站导航
项目相关
官方文档
首页
新闻
心情
关于
文章搜索
网站导航
项目相关
官方文档
登录
注册
go 信道
声明和存取 channel,是一种带有类型的管道引用类型 使
搜索
[[ slide_text ]]
[[ item.content ]]
1
1
go 信道
发布时间:
2022-12-04
作者:
枫枫
来源:
枫枫知道个人博客
Go
Golang
# 声明和存取 channel,是一种带有类型的管道引用类型 使用前需要make(Type, (缓冲容量)) 不带缓冲区的管道必须结合协程使用 可以查看长度len和容量cap ```Go package main import "fmt" func main() { // 声明一个string信道,容量为2 var ch chan string = make(chan string, 2) ch <- "枫枫" // 写入数据到信道中 ch <- "知道" s := <-ch // 从信道读取数据 fmt.Println(s) ss, ok := <-ch fmt.Println(ss, ok) close(ch) } ``` ```Go 存入:channel <- value 取出:value, (ok) <- channel 丢弃:<- channel 先进先出,自动阻塞 数据需要保持流动,否则会阻死报错 ``` 搭配协程使用 ```Go package main import "fmt" func pushNum(c chan int) { for i := 0; i < 100; i++ { c <- i } close(c) // 写完必须要关闭,不然会死锁 } func main() { var c1 chan int = make(chan int, 2) // 2表示缓冲区大小 go pushNum(c1) for value := range c1 { fmt.Println(value) } } ``` 多个协程函数,close就不能写在协程函数里了 ```Go package main import ( "fmt" "sync" ) var ch chan int = make(chan int, 10) var wg = sync.WaitGroup{} func pushNum() { for i := 0; i < 5; i++ { ch <- i } wg.Done() } func main() { wg.Add(2) go pushNum() go pushNum() wg.Wait() close(ch) for { res, ok := <-ch if !ok { break } fmt.Println(res) } } ``` # close 使用close之后就不能在继续写入了,但是还可以继续从缓冲区读取 1. close之后,读取的chan是数据类型的默认值 2. close之后,不能再往chan里面写入数据 3. for range之前必须要close # 可读可写 ```Go package main import "fmt" func main() { var ch chan int = make(chan int, 2) // 可读chan var readCh <-chan int = ch // 可写chan var writeCh chan<- int = ch writeCh <- 1 writeCh <- 2 fmt.Println(<-readCh) fmt.Println(<-readCh) } ``` # select ... case 适用于无法确认合适关闭信道的情况 通常结合for循环使用 select ... case会阻塞到某个分支可以继续执行时执行该分支,当没有可执行的分支是执行default分支 ```Go package main import "fmt" func main() { var ch1 chan int = make(chan int, 2) var ch2 chan int = make(chan int, 2) var ch3 chan int = make(chan int, 2) ch1 <- 1 ch2 <- 2 ch3 <- 3 select { // 监听多个chan的情况,是随机执行 case v := <-ch1: fmt.Println(v) case v := <-ch2: fmt.Println(v) case v := <-ch3: fmt.Println(v) default: fmt.Println("没有数据") } } ``` ```Go package main import "fmt" func PrimeNum(n int, c chan int) { for i := 2; i < n; i++ { if n%i == 0 { return } } c <- n } func main() { c := make(chan int) for i := 2; i < 100001; i++ { go PrimeNum(i, c) } Print: for { select { case v := <-c: fmt.Printf("%v\t", v) default: fmt.Printf("所有素数都已被找到") break Print } } } ```
1
1
上一篇:go 协程
下一篇:Go 泛型
你觉得文章怎么样
发布评论
165 人参与,0 条评论