go语言range的高级用法-使用range来接收通道里面的数据

embedded/2024/11/26 5:04:45/

在 Go 语言中,可以使用 for ... range 循环来遍历通道(channel)。for ... range 循环会一直从通道中接收值,直到通道关闭并且所有值都被接收完毕。

使用 for ... range 遍历通道

示例代码

下面是一个使用 for ... range 遍历通道的示例:

package mainimport ("fmt""time"
)func main() {// 创建一个有缓冲的通道ch := make(chan int, 5)// 启动一个 goroutine 向通道发送值go func() {for i := 0; i < 5; i++ {ch <- itime.Sleep(100 * time.Millisecond) // 模拟耗时操作}close(ch) // 关闭通道}()// 使用 for ... range 遍历通道for value := range ch {fmt.Println("Received:", value)}
}

在这里插入图片描述

解释

  1. 创建通道

    ch := make(chan int, 5)
    
    • make(chan int, 5) 创建一个容量为 5 的有缓冲通道。
  2. 启动 goroutine 发送值

    go func() {for i := 0; i < 5; i++ {ch <- itime.Sleep(100 * time.Millisecond) // 模拟耗时操作}close(ch) // 关闭通道
    }()
    
    • 启动一个 goroutine,向通道发送 0 到 4 的整数。
    • time.Sleep(100 * time.Millisecond) 模拟耗时操作,使发送操作之间有时间间隔。
    • close(ch) 关闭通道,表示不再发送新的值。
  3. 使用 for ... range 遍历通道

    for value := range ch {fmt.Println("Received:", value)
    }
    
    • for value := range ch 循环会一直从通道中接收值,直到通道关闭并且所有值都被接收完毕。
    • 每次接收到一个值,都会打印出来。

注意事项

  1. 关闭通道

    • 必须在发送完所有值后关闭通道,否则 for ... range 循环会一直阻塞,等待新的值。
    • 关闭通道后,不能再向通道发送值,否则会引发 panic。
  2. 多接收者

    • 如果有多个 goroutine 同时从同一个通道接收值,可能会出现竞争条件。建议使用互斥锁或其他同步机制来确保线程安全。
  3. 空通道

    • 对于无缓冲通道,如果没有接收者,发送操作会阻塞,直到有接收者准备接收值。

示例:多接收者

下面是一个多接收者从同一个通道接收值的示例:

package mainimport ("fmt""sync""time"
)func main() {// 创建一个有缓冲的通道ch := make(chan int, 5)// 启动一个 goroutine 向通道发送值go func() {for i := 0; i < 5; i++ {ch <- itime.Sleep(100 * time.Millisecond) // 模拟耗时操作}close(ch) // 关闭通道}()// 使用 sync.WaitGroup 等待所有接收者完成var wg sync.WaitGroup// 启动多个接收者 goroutinefor i := 0; i < 3; i++ {wg.Add(1)go func(id int) {defer wg.Done()for value := range ch {fmt.Printf("Receiver %d received: %d\n", id, value)}}(i)}// 等待所有接收者完成wg.Wait()
}

解释

  1. 启动多个接收者 goroutine

    for i := 0; i < 3; i++ {wg.Add(1)go func(id int) {defer wg.Done()for value := range ch {fmt.Printf("Receiver %d received: %d\n", id, value)}}(i)
    }
    
    • 启动三个接收者 goroutine,每个 goroutine 都使用 for ... range 循环从通道中接收值。
    • wg.Add(1) 增加 WaitGroup 的计数。
    • defer wg.Done() 在 goroutine 结束时减少 WaitGroup 的计数。
  2. 等待所有接收者完成

    wg.Wait()
    
    • 使用 wg.Wait() 等待所有接收者 goroutine 完成。

通过使用 for ... range 循环,可以方便地遍历通道中的值,直到通道关闭并且所有值都被接收完毕。这对于处理并发任务和数据流非常有用。


http://www.ppmy.cn/embedded/140544.html

相关文章

如何调试 chrome 崩溃日志(MAC)

引言 在使用 Chrome 浏览器的过程中&#xff0c;偶尔会遇到浏览器崩溃的情况。为了找出崩溃的原因并修复问题&#xff0c;我们需要对崩溃后的 .dmp 文件进行详细分析。本文将详细介绍如何从用户的系统中获取崩溃日志文件&#xff0c;使用 minidump_stackwalk 查看浏览器版本信…

金融服务的未来:测试自动化如何驱动合规、安全与创新

在快节奏、监管严格的金融服务领域&#xff0c;提供卓越的服务不仅仅关乎速度&#xff0c;还关乎管理巨大的复杂性。随着金融机构面临越来越大的创新压力&#xff0c;它们还肩负着维持严格的安全和合规标准的重任。 测试自动化不仅仅是一种工具&#xff1b;它 使团队能够 满怀…

HBase 原理

一、HBase系统架构 HBase采用主从架构&#xff0c;主要由以下几个组件组成&#xff1a; Client&#xff1a;客户端&#xff0c;可以是HBase Shell、Java API客户端、Rest API等&#xff0c;提供访问接口&#xff0c;并维护对应的缓存以加速HBase的访问。客户端缓存Region的位…

【设计模式】【创建型模式(Creational Patterns)】之抽象工厂模式(Abstract Factory Pattern)

1. 设计模式原理说明 工厂方法模式是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类。这种模式的核心思想是将对象的创建过程封装起来,使得代码更加灵活和易于扩展。 优点: 符合开闭原则(对扩展开放,…

Ubuntu22.04配置强化学习环境及运行相关Demo

什么是强化学习 强化学习&#xff08;Reinforcement Learning&#xff0c;简称 RL&#xff09;是机器学习中的一个重要分支&#xff0c;属于一种基于试错机制的学习方法。它通过让智能体&#xff08;Agent&#xff09;与环境&#xff08;Environment&#xff09;进行交互&…

【jvm】为什么java是半编译半解释型语言

目录 1. 编译过程2. 解释过程3. 即时编译&#xff08;JIT&#xff09;过程4. 半编译半解释型语言的特点 1. 编译过程 1.Java源代码首先会被编译成字节码&#xff08;Bytecode&#xff09;&#xff0c;这是一种与具体平台无关的中间代码。2.这一编译过程由Java编译器&#xff0…

RUST学习教程-安装教程

文章目录 参考文档安装教程更新卸载 参考文档 https://course.rs/first-try/installation.html 安装教程 Linux或者mac安装教程 curl --proto https --tlsv1.2 https://sh.rustup.rs -sSf | sh安装完成&#xff0c;当出现command not found的时候&#xff0c;需要source一下…

网络安全 - DOS

1.1.1 摘要 最近网络安全成了一个焦点&#xff0c;除了国内明文密码的安全事件&#xff0c;还有一件事是影响比较大的——Hash Collision DoS&#xff08;通过Hash碰撞进行的拒绝式服务攻击&#xff09;&#xff0c;有恶意的人会通过这个安全漏洞让你的服务器运行巨慢无比&…