Go语言channel

通道

通道(channel)是Go语言提供的一种在gorountine之间进行数据创术的通信机制。通道的声明非常简单,只需要使用chan 关键字即可,关闭则需要使用close函数。

注意:通过close函数关闭channel不是必须的。不主动关闭的通道,垃圾回收器会自动回收。文件操作的close姿势必须的。

创建通道

借助 make 函数

  • 先声明,后初始化

    go 复制代码
    var ch1 chan int          // 声明一个传输 int 的通道
    ch1 = make(chan int)	  // 初始化通道
    // ch1 = make(chan int, 3)	  
  • 声明并初始化

    go 复制代码
    ch2 := make(chan int)

channel写入数据

<- 表达式向channel中写入数据

go 复制代码
ch = make(chan int)  // 创建int通道 ch
ch <- 5				// 通道中写入 5

channel读出数据

-> 表达式从channel中读出数据

go 复制代码
ch = make(chan int)  // 创建int通道 ch
ch <- 5				// 通道中写入 5

num := <-ch  // 从通道中读取数据,放入 ch 中

阻塞式读写

通道channel写数据时,保证通道未满。否则,会阻塞写入,直到channel中的数据被读取,channel不满,此时写入数据。

通道channel读数据时,保证通道非空。否则,会阻塞读取,直到channel中有数据,然后读出数据。

缓冲channel和无缓冲channel

创建

go 复制代码
ch1 := make(chan int)     // 创建无缓冲 channel
ch2 := make(chan int, 3)  // 创建缓冲大小为 3 的channel
  • channel的摩尔你初始值是nil

读写

  • 无缓冲通道。写入一个数据后,立即阻塞,直到这个数据被取出。
  • 有缓冲通道。当准备往通道中写入数据时,如果通道已满,则阻塞,直到通道不满。否则,直接写入,即使写入数据后,通道满了,也不阻塞。

简单的说,无缓冲通道的写阻塞发生在数据写入后,有缓冲通道的阻塞发生在数据写入前,通道已满。

小技巧:缓冲channel的缓冲区元素个数和缓冲区容量,可以通过len函数和cap函数来返回。

误区

  • 不能把无缓冲通道看成缓冲大小为 1 1 1的有缓冲通道
go 复制代码
ch := make(chan int)       // 无缓冲通道
ch := make(chan int, 1)    // 有缓冲通道

给出一段代码示例,辅助理解:

  • 使用上面两种通道,相同的代码结果是不一样的。
cpp 复制代码
package main

import "fmt"
import "time"

func main() {
	c := make(chan int)          // 运行结果输出一个 6
	// c := make(chan int, 1)    // 运行结果输出两个 6
	go w(c, 6)
	time.Sleep(1*time.Second)
}

func w(c chan int, x int){
	fmt.Println(x)
	c <- x
	close(c)
	fmt.Println(x)
}

注意: 当主goroutine结束的时候,所有其他的goroutine都会被强制结束。

channel作为函数参数

Go语言在channel做函数参数的时候可以指定通道的方向,也就是指定该通道是发送数据还是接受数据。

通道分两种类型:无方向通道和双向通道,默认创建的是双向通道。

go 复制代码
func f1(c chan int) {}     // c 是 双向通道, 可读可写
func f2(c chan<- int) {}   // c 是 写通道, 只能写数据,不能读数据
func f3(c <-chan int) {}   // c 的 读通道,只能读数据,不能写数据

注意:双向通道以指定方向的参数方式,进行隐式转换成读通道或写通道。反之,则不行。

相关推荐
云栖梦泽6 分钟前
鸿蒙应用签名与上架全流程:从开发完成到用户手中
开发语言·鸿蒙系统
神奇的程序员37 分钟前
从已损坏的备份中拯救数据
运维·后端·前端工程化
爱上妖精的尾巴44 分钟前
6-4 WPS JS宏 不重复随机取值应用
开发语言·前端·javascript
oden1 小时前
AI服务商切换太麻烦?一个AI Gateway搞定监控、缓存和故障转移(成本降40%)
后端·openai·api
李慕婉学姐2 小时前
【开题答辩过程】以《基于Android的出租车运行监测系统设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·后端·vue
小鸡吃米…2 小时前
Python 列表
开发语言·python
m0_740043732 小时前
SpringBoot05-配置文件-热加载/日志框架slf4j/接口文档工具Swagger/Knife4j
java·spring boot·后端·log4j
kaikaile19952 小时前
基于C#实现一维码和二维码打印程序
开发语言·c#
我不是程序猿儿3 小时前
【C#】画图控件的FormsPlot中的Refresh功能调用消耗时间不一致缘由
开发语言·c#
rit84324993 小时前
C# Socket 聊天室(含文件传输)
服务器·开发语言·c#