channel 是 goroutine 之间的通讯桥梁
定义chan 分为五种
可读可取 c:=make(chan int)
可读 var readChan <-chan int = c
可取 var setChan chane<- int = c
有缓冲 c:=make(chan int,5)
无缓冲 c:=make(chan int)
有缓冲 c:=make(chan int,5)
package main
import "fmt"
func main() {
c := make(chan int, 1)
c <- 1
fmt.Println(<-c)
}
无缓冲 c:=make(chan int),可在设置 channel 和 获取 channel 打断点进行调试
c := make(chan int)
go func() {
c <- 1
}()
fmt.Println(<-c)
有缓冲 c:=make(chan int,5),可在设置 channel 和 获取 channel 打断点进行调试
package main
import "fmt"
func main() {
c := make(chan int, 5)
go func() {
for i := 1; i <= 5; i++ {
c <- i
}
}()
for i := 1; i <= 5; i++ {
fmt.Println(<-c)
}
}
无缓冲 c:=make(chan int),可在设置 channel 和 获取 channel 打断点进行调试
package main
import "fmt"
func main() {
c := make(chan int)
go func() {
for i := 1; i <= 5; i++ {
c <- i
}
}()
for i := 1; i <= 5; i++ {
fmt.Println(<-c)
}
}
可读可写
package main
import "fmt"
func main() {
c := make(chan int, 5)
var readC <-chan int = c
var writeC chan<- int = c
writeC <- 1
fmt.Println(<-readC)
}
关闭 channel:channel 开启以后是可以 close 的,当你觉得不再需要并且已经 set 完成的时候,你就需要去 close 它
package main
import "fmt"
func main() {
c := make(chan int, 3)
c <- 1
c <- 2
c <- 3
close(c)
fmt.Println(<-c)
fmt.Println(<-c)
fmt.Println(<-c)
}
需要注意,如果用到了 range 则必须在 range 之前就给它关闭
package main
import "fmt"
func main() {
c := make(chan int, 3)
c <- 1
c <- 2
c <- 3
close(c)
for v := range c {
fmt.Println(v)
}
}
select:每次执行打印的结果可能不一致
package main
import "fmt"
func main() {
c1 := make(chan int, 1)
c2 := make(chan int, 1)
c3 := make(chan int, 1)
c1 <- 1
c2 <- 1
c3 <- 1
select {
case <-c1:
fmt.Println("c1")
case <-c2:
fmt.Println("c2")
case <-c3:
fmt.Println("c3")
default:
fmt.Println("c0")
}
}
channel 是 goroutine 之间的通讯桥梁:
package main
import "fmt"
func main() {
c := make(chan int)
var readC <-chan int = c
var writeC chan<- int = c
go SetChan(writeC)
GetChan(readC)
}
func SetChan(writeC chan<- int) {
for i := 1; i <= 5; i++ {
fmt.Println("writeCBefore")
writeC <- i
fmt.Println("writeCAfter")
}
}
func GetChan(readC <-chan int) {
for i := 1; i <= 5; i++ {
fmt.Println(<-readC)
}
}
执行结果
writeCBefore
writeCAfter
writeCBefore
1
2
writeCAfter
writeCBefore
writeCAfter
writeCBefore
3
4
writeCAfter
writeCBefore
writeCAfter
5
结果解释:因为这个是无缓冲区的。如果设置为 1 缓冲区则会开始交替时执行,这是因为在遇到向 channel 写入值,是否往下执行是交替的,也就是说是随机的,原因是因为协程都是利用同一 cpu 在不同时间片上运行的