【Go快速入门】— golang高阶:channel

Go Alice 2年前 (2022-04-01) 421次浏览 0个评论

一、channel

1、channel 的定义

【Go 快速入门】—  golang 高阶:channel
使用make初始化 channel

make(chan Type)            // 等价于 make(chan Type, 0)
make(chan Type, capacity)  // capacity 用来表示当前 channel 是有缓冲的还是无缓冲的

//向 channel 写数据
channel <- value     //发送 value 到 channel

//从 channel 读数据
<-channel            //接收并将其丢弃
x := <-channel       //从 channel 中接收数据,并赋值给 x
x, ok := <-channel   //功能同上,同时检查通道是否已经关闭或者是否为空

2、channel 的使用

func main()  {
	//定义一个 channel
	c := make(chan int)

	go func ()  {
		defer fmt.Println("goroutine 结束")

		fmt.Println("goroutine 正在运行...")

		c <- 666 //将 666 发送给 c
	}()

	num := <-c //从 c 中接受数据,并赋值给 num

	fmt.Println("num = ", num)

	fmt.Println("main goroutine 结束...")
}

【Go 快速入门】—  golang 高阶:channel

二、有无缓冲的 channel

1、无缓冲的 channel

【Go 快速入门】—  golang 高阶:channel

2、有缓冲的 channel

【Go 快速入门】—  golang 高阶:channel

func main()  {
	c := make(chan int, 3) //带有缓冲的 channel

	fmt.Println("len() = ", len(c), " cap(c) = ", cap(c))

	go func() {
		defer fmt.Println("子 go 程结束")	

		for i := 0; i < 3; i++ {
			c <- i
			fmt.Println("子 go 程正在运行, 发送的元素=", i, " len(c)=", len(c), " cap(c)=", cap(c))
		}
	}()

	time.Sleep(2 * time.Second)

	for i := 0; i < 3; i++ {
		num := <- c //从 c 中接收数据,并赋值给 num
		fmt.Println("num = ", num)
	}

	fmt.Println("main 结束")
}

【Go 快速入门】—  golang 高阶:channel

三、关闭 channel

func main()  {
	c := make(chan int)

	go func() {
		for i := 0; i < 5; i++ {
			c <- i
		}

		//close 可以关闭一个 channel
		close(c)
	}()
	
	for {
		//ok 如果为 true 表示 channel 没有关闭,如果为 false 表示 channel 已经关闭
		if data, ok := <-c; ok {
			fmt.Println(data)
		} else {
			break
		}
	}

	fmt.Println("Main Finished...")
}

【Go 快速入门】—  golang 高阶:channel

四、channel 与 range

func main()  {
	c := make(chan int)

	go func() {
		for i := 0; i < 5; i++ {
			c <- i
		}

		//close 可以关闭一个 channel
		close(c)
	}()
	
	//可以使用 range 来迭代不断操作 channel
	for data := range c {
		fmt.Println(data)
	}

	fmt.Println("Main Finished...")
}

【Go 快速入门】—  golang 高阶:channel

五、channel 与 select

单流程下⼀个 go 只能监控⼀个 channel 的状态,select 可以完成监控多个 channel 的状态。

select {
case <- chan1:
	// 如果 chan1 成功读到数据,则进行该 case 处理语句
case chan2 <- 1:
	// 如果成功向 chan2 写入数据,则进行该 case 处理语句
default:
	// 如果上面都没有成功,则进入 default 处理流程
}

例:

func fibonacii(c, quit chan int)  {
	x, y := 1, 1

	for {
		select {
		case c <- x:
			//如果 c 可写,则该 case 就会进来
			x = y
			y = x + y
		case <-quit:
			//如果 quit 可读,则进入该 case
			fmt.Println("quit")
			return
		}
	}
}

func main()  {
	c := make(chan int)
	quit := make(chan int)

	//sub  go
	go func() {
		for i := 0; i < 6; i++ {
			fmt.Println(<-c)
		}

		quit <- 0
	}()

	//main go
	fibonacii(c, quit)
}

【Go 快速入门】—  golang 高阶:channel

 

分享:Golang 学习视频地址:8 小时转职 Golang 工程师(如果你想低成本学习 Go 语言)


女程序员博客 , 版权所有丨本站采用BY-NC-SA协议进行授权 , 转载请注明【Go 快速入门】— golang 高阶:channel

【声明】:本博客仅为分享信息,不参与任何交易,也非中介,所有内容仅代表个人观点,均不作直接、间接、法定、约定的保证,读者购买风险自担。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。

【关于安全】:任何 IDC 都有倒闭和跑路的可能,备份永远是最佳选择,服务器也是机器,不勤备份是对自己极不负责的表现,请保持良好的备份习惯。

喜欢 (1)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址