当前位置: 首页 > news >正文

Go基础编程 - 09 - 通道(channel)

通道(channel)

    • 1. 声明
    • 2. channel的操作
    • 3. 无缓冲通道
    • 4. 有缓冲通道
    • 5. 如何优雅的从通道循环取值
    • 6. 单向通道
    • 7. 异常总结

上一篇:结构体


Go语言的并发模式:不要通过共享内存来通信,而应该通过通信来共享内存

Go语言的通道(channel)是一种特殊类型,遵循先进先出(FIFO)的原则,声明channel时需要指定元素类型。

channel是一种通信机制,用于在不同的goroutine之间传递数据。

1. 声明

channel 是一种引用类型,空值是 nil。声明后的 channel 变量是未初始化的,需要使用make函数初始化。

  • 声明channel:var 变量 chan 元素类型
  • 创建channel:ch := make(chan 元素类型, 缓冲大小)

元素类型:通道中存放的数据类型。

package mainimport "fmt"func main() {// 声明var ch chan intfmt.Println(ch) // <nil>// 初始化ch = make(chan int, 3)
}

2. channel的操作

  • 操作符:<-
  • 发送(send):ch <- 元素值
  • 接收(receive):元素值 := <-ch
  • 关闭(close):close(ch)
package mainimport "fmt"func main() {ch := make(chan int, 3)ch <- 1 // 把 1 发送到 chch <- 2ch <- 3//ch <- 4  // 超出缓冲大小:fatal error: all goroutines are asleep - deadlock!i := <-ch  // 从 ch 接收一个值,并赋值给 ifmt.Println(i)<-ch       // 从 ch 接收一个值,并丢弃<-chj, ok := <-ch   // 通道未关闭且无元素值,则堵塞:fatal error: all goroutines are asleep - deadlock!fmt.Printf("i = %d, j = %d, ok = %v\n", i, j, ok)ch <- 4close(ch)   // 关闭通道 ch//ch <- 5     // 通道关闭后,不可再发送:panic: send on closed channelk, ok := <-ch   // 通道关闭后,若通道内还有值,接收依然可以接收通道中的元素。fmt.Printf("k = %d, ok = %v\n", k, ok)m, ok := <-ch   // 通道关闭且无元值,得到对应类型的零值。ok为false说明通道已没有元素值可取了fmt.Printf("k = %d, ok = %v\n", m, ok)
}

关闭后的通道具有以下特点:

  1. 通道关闭后,发送操作引发 panic

  2. 通道关闭后,若通道内还有值,接收操作依然可以接收通道中的元素。

  3. 通道关闭且没有值,接收操作会得到对应类型的零值。接收表达式可接收两个值,第一个值为接收到的元素值,第二个值为bool类型,如果为false,则说明通道已没有元素值可取了,且通道已关闭。

    注:若通道未关闭且无元素值,接收操作堵塞。

  4. 关闭一个已关闭的通道,会引发panic。

3. 无缓冲通道

又称为堵塞通道。无论send还是receive一开始执行就会被堵塞,直到配对的操作也开始执行,才会继续传递。

同步方式传递数据:使用无缓冲通道进行通信将导致发送和接收的goroutine同步化。因此,无缓冲通道也被称为同步通道。

package mainimport "fmt"func main() {ch := make(chan int)go func(c chan int) {ret := <-cfmt.Println("接收成功", ret)}(ch)ch <- 10fmt.Println("发送成功")
}

无缓冲通道

4. 有缓冲通道

只要通道的容量大于零,那么该通道就是有缓冲的通道,通道的容量表示通道中能存放元素的数量。

获取通道内元素数量:len(ch)

获取通道的容量:cap(ch)

func main() {ch := make(chan int, 10) // 创建一个容量为1的有缓冲区通道ch <- 10fmt.Println("发送成功")
}

异步方式传递数据
有缓冲通道

5. 如何优雅的从通道循环取值

通过channel发送有限数据时,可以通过close函数关闭通道来告诉通道接收值的goroutine停止等待。

package mainimport "fmt"func main() {ch1 := make(chan int)ch2 := make(chan int)// goroutinego func() {for i := 0; i < 100; i++ {ch1 <- i}close(ch1)}()go func() {for {i, ok := <-ch1  if !ok {    // ok为false,表面通道已关闭且没有元素值可取了break}ch2 <- i * i}close(ch2)}()// 主goroutinefor i := range ch2 { // 通道关闭后会退出for range循环fmt.Println(i)}
}

6. 单向通道

有的时候我们会将通道作为参数在多个任务函数间传递,很多时候我们在不同的任务函数中使用通道都会对其进行限制,比如限制通道在函数中只能发送或只能接收。

Go语言中提供了单向通道来处理这种情况。例如,我们把上面的例子改造如下:

package mainimport "fmt"func counter(out chan<- int) { // 限制out仅为发送通道for i := 0; i < 100; i++ {out <- i}close(out)
}func squarer(out chan<- int, in <-chan int) {for i := range in {out <- i * i}close(out)
}func printer(in <-chan int) {   // in限制为接收通道for i := range in {fmt.Println(i)}
}func main() {ch1 := make(chan int)ch2 := make(chan int)go counter(ch1) // GO语言会自动把双向通道转换为函数所需要的单向通道go squarer(ch2, ch1)printer(ch2)
}

7. 异常总结

异常总结

相关文章:

Go基础编程 - 09 - 通道(channel)

通道&#xff08;channel&#xff09; 1. 声明2. channel的操作3. 无缓冲通道4. 有缓冲通道5. 如何优雅的从通道循环取值6. 单向通道7. 异常总结 上一篇&#xff1a;结构体 Go语言的并发模式&#xff1a;不要通过共享内存来通信&#xff0c;而应该通过通信来共享内存。 Go语言…...

[SAP ABAP] 数据类型

1.基本数据类型 示例1 默认定义的基本数据类型是CHAR数据类型 输出结果: 示例2 STRING数据类型用于存储任何长度可变的字符串 输出结果: 示例3 DATE数据类型用于存储日期信息&#xff0c;并且可以存储8位数字 输出结果: 提示Tips&#xff1a;日期和时间类型的变量可以直接进…...

什么是Vue开发技术

概述 Vue.js 是一个用于构建用户界面的渐进式框架&#xff0c;它设计得非常灵活&#xff0c;可以轻松地被集成到任何项目中。 vue是视图的发音&#xff0c;其目的是帮助开发者易于上手&#xff0c;提供强大的功能构建复杂的应用程序 示例 以下是vue基本的语法概述 声明式渲…...

【QT】

通信服务端实现 widget.h文件 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTcpServer>//服务器类 #include <QMessageBox>//消息 #include <QTcpServer> #include <QList> #include <QTcpSocket> QT_BEGIN_NAMESPAC…...

【转载】使用 .NET Upgrade Assistant(升级助手)升级 .NET 老旧版本项目

使用 .NET Upgrade Assistant&#xff08;升级助手&#xff09;升级 .NET 老旧版本项目&#xff1a;https://blog.csdn.net/ChaITSimpleLove/article/details/134711604...

SpringBoot如何自定义启动Banner 以及自定义启动项目控制台输出信息 类似于若依启动大佛 制作教程

前言 Spring Boot 项目启动时会在控制台打印出一个 banner&#xff0c;下面演示如何定制这个 banner。 若依也会有相应的启动动画 _ooOoo_o8888888o88" . "88(| -_- |)O\ /O____/---\____. \\| |// ./ \\||| : |||// \/ _||||| -:- |||||- \| | \\…...

访问控制列表(Access Control Lists,ACL)与哈希查找的爱恨情怨

访问控制列表&#xff08;Access Control Lists&#xff0c;ACL&#xff09;与哈希查找 什么是访问控制列表ACL&#xff1f;直接说ACL是干啥的ACL概念为什么需要ACLACL类型ACL匹配机制使用例子 哈希查找什么是哈希查找&#xff1f;哈希查找的基本原理哈希查找的步骤 哈希查找在…...

一文讲清楚分销裂变是什么?怎么做好分销裂变?【附案例】

在数字化营销日益盛行的今天&#xff0c;分销裂变作为一种高效的推广手段&#xff0c;受到了越来越多企业的青睐。那么&#xff0c;分销裂变究竟是什么&#xff1f;我们又该如何做好分销裂变呢&#xff1f;林叔将从定义、方法以及案例分析三个方面进行阐述。 一、分销裂变是什…...

Mybatis Plus 详解 IService、BaseMapper、自动填充、分页查询功能

结构直接看目录 前言 MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 愿景 我们的愿景是成为 MyBatis 最好的搭档&#xff0c;就像 魂斗罗 中的 1P、2P&#xff0c;基友搭配&#xff0c;效…...

鸿蒙开发组件:【FA模型的Context】

FA模型的Context FA模型下只有一个Context。Context中的所有功能都是通过方法来提供的&#xff0c;它提供了一些featureAbility中不存在的方法&#xff0c;相当于featureAbility的一个扩展和补全。 接口说明 FA模型下使用Context&#xff0c;需要通过featureAbility下的接口…...

Linux下手动修改服务器时间(没网环境下)

在客户服务器上更新程序时&#xff0c;发现服务器时间不对&#xff0c;现在应该是下午13:44:00&#xff0c;但服务器却显示为&#xff1a;21:40:53&#xff0c;所有是不对的。 date解决办法&#xff1a; 1、由于服务器是没有网的&#xff0c;只能手动设置时间&#xff0c;输入…...

嵌入式系统软件开发环境_3.主要功能和典型产品

1.嵌入式系统软件开发环境的主要功能 由于嵌入式系统的软件开发通常采用的是交叉开发方式&#xff0c;因此其开发环境中的工具应支持这种交叉开发的特点。嵌入式系统软件开发环境的功能应覆盖嵌入式软件开发过程&#xff0c;即编码过程、编译过程、构建过程、下载过程、调式过程…...

使用Python保护或加密Excel文件的7种方法

目录 安装Python Excel库 Python 使用文档打开密码保护 Excel 文件 Python 使用文档修改密码保护 Excel 文件 Python 将 Excel 文件标记为最终版本 Python 保护 Excel 工作表 Python 在保护 Excel 工作表的同时允许编辑某些单元格 Python 锁定 Excel 工作表中的特定单元…...

【嵌入式Linux】<总览> 文件IO(更新中)

文章目录 前言 一、常用函数 1. open函数 2. close函数 3. write函数 4. read函数 5. dup函数 6. dup2函数 二、文件读写细节 1. 换行符 2. 文件描述符 3. errno和perror 前言 在Linux系统中&#xff0c;一切皆文件。因此&#xff0c;掌握Linux下文件IO常用的函数…...

【无线传感网】分簇路由算法介绍

目录 1、LEACH路由算法 2、PEGASIS 算法 3、TEEN 算法 5、APTEEN 5、LEACH-C 算法 无线传感网中的路由协议就是寻找一条路径让网络中节点沿着这条路径将数据信息传输出去。路由协议的两大关键要点就是路径的优化和数据的分组,在传统计算机网络中,是将网络的拓扑…...

java 利用poi读取wps嵌入式图片,自测

代码 主要工具类 需要引入依赖&#xff1a; package com.chenkang.demo.util;import cn.wps.officeDocument.x2017.etCustomData.CellImagesDocument; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.…...

git 常用操作指令

文章目录 git clonegit configgit addgit commitgit rmgit branch/checkoutgit pull/pushgit rebash/merge git clone git clone 可以将一个远程 Git 仓库拷贝到本地&#xff0c;让自己能够查看该项目&#xff0c;或者进行修改。 拷贝项目命令格式如下&#xff1a;git clone [u…...

达梦导入导出

针对导出数据库表结构通常有 3 种方法&#xff1a; 使用 DTS 导出 打开 DTS 迁移工具&#xff0c;选择【DM-->SQL】并链接到数据库中&#xff0c;如下图所示&#xff1a; 添加定义脚本&#xff0c;并选择【迁移范围】&#xff08;仅迁移对象定义&#xff09;&#xff0c;如…...

超级数据查看器 教程pdf 1-31集 百度网盘

百度网盘链接 提取码1234https://pan.baidu.com/s/1s_2lbwZ2_Su83vDElv76ag?pwd1234 通过百度网盘分享的文件&#xff1a;超级数据查看器 … 链接:https://pan.baidu.com/s/1s_2lbwZ2_Su83vDElv76ag?pwd1234 提取码:1234 复制这段内容打开「百度网盘APP 即可获取」...

一、开发环境安装 Avalonia

1、概述 官网中是这么介绍Avalonia的&#xff0c;Avalonia是一个强大的框架&#xff0c;使开发人员能够使用.NET创建跨平台应用程序。它使用自己的渲染引擎绘制UI控件&#xff0c;确保在Windows、macOS、Linux、Android、iOS和WebAssembly等不同平台上具有一致的外观和行为。这…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

基于单片机的宠物屋智能系统设计与实现(论文+源码)

本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢&#xff0c;连接红外测温传感器&#xff0c;可实时精准捕捉宠物体温变化&#xff0c;以便及时发现健康异常&#xff1b;水位检测传感器时刻监测饮用水余量&#xff0c;防止宠物…...