多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### chanel类型 用于多个协程之间的通信,channel是一种特殊类型,和map类似 > **var 通道变量 chan 通道类型** > 定义channel时,也需要定义发送到channel的值的类型,可以使用make()函数创建 > **make(chan Type) ,等价于 make(chan Type, 0)** > **make(chan Type, capacity)** > Type,类型 > 当capacity (容量) 为0时,channel是无缓冲堵塞读写的,当capacity大于0时,channel是有缓冲,非堵塞的,直到写满capacity个元素才堵塞写入。 channel 通过 "<-" 来接收和发送数据 默认channel收发数据都是堵塞的 ``` channel <- value //发送value到channel <- channel //接收并将其丢弃 x := <- channel //从channel中接收数据,赋值给x x, ok = <- channel //从channel中接收数据赋值给x,检查通道是否关闭将此状态赋值给ok ``` ``` package main import ( "fmt" "time" ) func main() { // 创建通道 ch := make(chan string) go func() { // 打印通道接收的 值 fmt.Println(<-ch) }() // 发送 hello 到到通道 ch ch <- "hello" time.Sleep(time.Second) } 结果: hello ``` ### 缓冲机制 无缓冲通道,是指接收前没有能力保存任何值的通道 > **make(chan Type),等价于 make(chan Type, 0)** > 无缓冲通道ch,只有当接收者接收到数据,发送者才能继续发送 ``` package main import ( "fmt" "time" ) func main() { ch := make(chan int, 0) go func() { for i := 0; i < 3; i++ { fmt.Printf("长度len() = %v, 容量cap(ch)=%v\n", len(ch), cap(ch)) // 把 i 发送给通道 ch ch <- i } }() for i := 0; i < 3; i++ { time.Sleep(time.Second) // 打印接收的通道 ch fmt.Println(<-ch) } } 结果: 长度len() = 0, 容量cap(ch)=0 0 长度len() = 0, 容量cap(ch)=0 1 长度len() = 0, 容量cap(ch)=0 2 ``` 有缓存通道,是指被接收前能储存一个或者多个值的通道 >**make(chan Type, capatity)** ``` package main import ( "fmt" "time" ) func main() { ch := make(chan int, 3) go func() { for i := 0; i < 3; i++ { fmt.Printf("长度len() = %v, 容量cap(ch)=%v\n", len(ch), cap(ch)) // 把 i 发送给通道 ch ch <- i } }() for i := 0; i < 3; i++ { time.Sleep(time.Second) // 打印接收的通道 ch fmt.Println(<-ch) } } 结果: 长度len() = 0, 容量cap(ch)=3 长度len() = 1, 容量cap(ch)=3 长度len() = 2, 容量cap(ch)=3 0 1 2 ``` ### close 和range close和range 让通道停止不必要的等待 . **close** channel不像文件可以经常关闭,只有当你没有需要发送的数据时,或者想结束range循环之类的,才会关闭 关闭后无法再错向channel发送数据,但是可以从channel接收 对于nil channel(空通道)无论接收还是发送都会堵塞 ``` package main import "fmt" func main() { // 创建一个通道 ch := make(chan int, 3) go func() { for i := 0; i < 3; i++ { fmt.Printf("长度len() = %v, 容量cap(ch)=%v\n", len(ch), cap(ch)) // 发送i给通道 ch <- i } // 关闭通道 close(ch) }() for i := 0; i < 3; i++ { // 如果通道里面有值 ok 就等于 true 没有了就是false 执行else if val, ok := <-ch; ok == true { fmt.Println(val) } else { return } } } 结果: 长度len() = 0, 容量cap(ch)=3 长度len() = 0, 容量cap(ch)=3 长度len() = 1, 容量cap(ch)=3 0 1 2 ``` . **range遍历通道** ``` for data:= range ch{ } ``` ``` package main import "fmt" func main() { // 创建一个通道 ch := make(chan int, 3) go func() { for i := 0; i < 3; i++ { fmt.Printf("长度len() = %v, 容量cap(ch)=%v\n", len(ch), cap(ch)) // 发送i给通道 ch <- i } // 关闭通道 close(ch) }() // 遍历通道 for data := range ch { fmt.Println(data) } } 结果: 长度len() = 0, 容量cap(ch)=3 长度len() = 0, 容量cap(ch)=3 长度len() = 1, 容量cap(ch)=3 0 1 2 ```