创建channael
var ch chan int
声明的通道需要初始化之后才能使用
make(chan 元素类型,[缓冲大小])
ch1 := make(chan int)
channel操作
通道有发送(send),接收(receive)和关闭(close)三种操作
发送和接收都使用<-符号
func main() {
ch := make(chan int)
ch <- 10
fmt.Println("发送成功")
}
上面的代码执行会报错:fatal error: all goroutines are asleep - deadlock!
因为我们使用ch := make(chan int)创建的是无缓冲的通道,无缓冲的通道只有在有人接收值的时候才能发送值。就像你住的小区没有快递柜和代收点,快递员给你打电话必须要把这个物品送到你的手中,简单来说就是无缓冲的通道必须有接收才能发送。
上面的代码会阻塞在ch <- 10这一行代码形成死锁,那如何解决这个问题呢?
一种方法是启用一个goroutine去接收值,例如:
func recv(c chan int) {
ret := <-c
fmt.Println("ret:", ret)
}
func main() {
ch := make(chan int)
defer close(ch)
go recv(ch)
ch <- 10
fmt.Println("ch:", ch)
}
还可以:
func main() {
ch := make(chan int, 1) // 创建一个容量为1的有缓冲区通道
ch <- 10
fmt.Println("发送成功")
}
取值
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
// 开启goroutine将0~100的数发送到ch1中
go func() {
for i := 0; i < 100; i++ {
ch1 <- i
}
close(ch1)
}()
// 开启goroutine从ch1中接收值,并将该值的平方发送到ch2中
go func() {
for {
i, ok := <-ch1 // 通道关闭后再取值ok=false
if !ok {
break
}
ch2 <- i * i
}
close(ch2)
}()
// 在主goroutine中从ch2中接收值打印
for i := range ch2 { // 通道关闭后会退出for range循环
fmt.Println(i)
}
}
单项通道
package main
import (
"fmt"
)
// 接受一个只写 channel 作为参数
func producer(send chan<- int) {
for i := 0; i < 3; i++ {
send <- i
}
// 使用 close 关闭 channel
close(send)
}
// 接受一个只读 channel 作为参数
func consumer(receive <-chan int) {
for num := range receive {
fmt.Println("receive num =", num)
}
}
func main() {
fmt.Println("嗨客网(www.haicoder.net)")
// 创建一个双向channel
channel := make(chan int)
go producer(channel)
consumer(channel)
}