GO语言:channel通道_{"promotecode" "8eby","channelname" "10000"}

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

一、 什么是通道

1.1 通道的概念

通道是什么,通道就是goroutine之间的通道。它可以让goroutine之间相互通信。

每个通道都有与其相关的类型。该类型是通道允许传输的数据类型。(通道的零值为nil。nil通道没有任何用处,因此通道必须使用类似于map和切片的方法来定义。)

1.2 通道的声明

声明一个通道和定义一个变量的语法一样:

//声明通道
var 通道名 chan 数据类型
//创建通道:如果通道为nil(就是不存在),就需要先创建通道
通道名 = make(chan 数据类型)

示例代码:

package main
​
import "fmt"
​
func main() {
    var a chan int
    if a == nil {
        fmt.Println("channel 是 nil 的, 不能使用,需要先创建通道。。")
        a = make(chan int)
        fmt.Printf("数据类型是: %T", a)
    }
}
​

运行结果:

​
channel 是 nil 的, 不能使用,需要先创建通道。。
数据类型是: chan int

也可以简短的声明:

a := make(chan int) 

1.3 channel的数据类型

channel是引用类型的数据,在作为参数传递的时候,传递的是内存地址。

示例代码:

package main
​
import (
    "fmt"
)
​
func main() {
    ch1 := make(chan int)
    fmt.Printf("%T,%p\n",ch1,ch1)
​
    test1(ch1)
​
}
​
func test1(ch chan int){
    fmt.Printf("%T,%p\n",ch,ch)
}
​
​

运行结果:

我们能够看到,ch和ch1的地址是一样的,说明它们是同一个通道。

1.4 通道的注意点

Channel通道在使用的时候,有以下几个注意点:

  • 1.用于goroutine,传递消息的。
  • 2.通道,每个都有相关联的数据类型,nil chan,不能使用,类似于nil map,不能直接存储键值对
  • 3.使用通道传递数据:<- chan <- data,发送数据到通道。向通道中写数据 data <- chan,从通道中获取数据。从通道中读数据
  • 4.阻塞: 发送数据:chan <- data,阻塞的,直到另一条goroutine,读取数据来解除阻塞 读取数据:data <- chan,也是阻塞的。直到另一条goroutine,写出数据解除阻塞。
  • 5.本身channel就是同步的,意味着同一时间,只能有一条goroutine来操作。

最后:通道是goroutine之间的连接,所以通道的发送和接收必须处在不同的goroutine中。

二、通道的使用语法

2.1 发送和接收

发送和接收的语法:

data := <- a // read from channel a  
a <- data // write to channel a

在通道上箭头的方向指定数据是发送还是接收。

另外:

v, ok := <- a //从一个channel中读取

2.2 发送和接收默认是阻塞的

一个通道发送和接收数据,默认是阻塞的。当一个数据被发送到通道时,在发送语句中被阻塞,直到另一个Goroutine从该通道读取数据。相对地,当从通道读取数据时,读取被阻塞,直到一个Goroutine将数据写入该通道。

这些通道的特性是帮助Goroutines有效地进行通信,而无需像使用其他编程语言中非常常见的显式锁或条件变量。

示例代码:

package main
​
import "fmt"
​
func main() {
    var ch1 chan bool       //声明,没有创建
    fmt.Println(ch1)        //<nil>
    fmt.Printf("%T\n", ch1) //chan bool
    ch1 = make(chan bool)   //0xc0000a4000,是引用类型的数据
    fmt.Println(ch1)
​
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println("子goroutine中,i:", i)
        }
        // 循环结束后,向通道中写数据,表示要结束了。。
        ch1 <- true
​
        fmt.Println("结束。。")
​
    }()
​
    data := <-ch1 // 从ch1通道中读取数据
    fmt.Println("data-->", data)
    fmt.Println("main。。over。。。。")
}
​

运行结果:

在上面的程序中,我们先创建了一个chan bool通道。然后启动了一条子Goroutine,并循环打印10个数字。然后我们向通道ch1中写入输入true。然后在主goroutine中,我们从ch1中读取数据。这一行代码是阻塞的,这意味着在子Goroutine将数据写入到该通道之前,主goroutine将不会执行到下一行代码。因此,我们可以通过channel实现子goroutine和主goroutine之间的通信。当子goroutine执行完毕前,主goroutine会因为读取ch1中的数据而阻塞。从而保证了子goroutine会先执行完毕。这就消除了对时间的需求。在之前的程序中,我们要么让主goroutine进入睡眠,以防止主要的Goroutine退出。要么通过WaitGroup来保证子goroutine先执行完毕,主goroutine才结束。

示例代码:以下代码加入了睡眠,可以更好的理解channel的阻塞

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

UcdJK-1715525897961)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值