golang基础-goroutine初识、chan存取、goroutine和chan相结合、关闭chan、range取、单元测试

本文主要是介绍golang基础-goroutine初识、chan存取、goroutine和chan相结合、关闭chan、range取、单元测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

      • goroute初识
      • channel存取
      • 开启goroute实现chan之间的同步存取
      • channel关闭
      • range
        • 单元测试

goroute初识

package mainimport ("fmt"// "os""time"
)func test(){var i int for {fmt.Println(i)time.Sleep(time.Second)i++}
}func main() {go test()for {fmt.Println("running in main")time.Sleep(time.Second)}
}

利用go 启动一个goroute

channel存取

先进先出
线程安全,多个goroutine同时访问,不需要加锁
channel是有类型的,一个整数的channel只能存放整数

package mainimport ("fmt"// "fmt")
type Stu struct{name string
}func main() {//int类型var intChan chan int intChan = make(chan int,10)intChan <- 10a := <- intChanfmt.Println(a)fmt.Println("--------/map类型---------")//map类型var mapChan chan map[string]stringmapChan = make(chan map[string]string,10)m:= make(map[string]string,16)m["stu01"] = "001"m["stu02"] = "002"m["stu03"] = "003"mapChan <- mb := <- mapChanfmt.Println(b)fmt.Println("--------结构体---------")//结构体var stuChan chan StustuChan = make(chan Stu,10)stu:= Stu{name:"safly",}stuChan <- stutempStu := <- stuChanfmt.Println(tempStu)fmt.Println("--------结构体内存地址---------")//结构体内存地址值var stuChanId chan *StustuChanId = make(chan *Stu,10)stuId := &Stu{name:"safly",}stuChanId <- stuIdtempStuId := <- stuChanIdfmt.Println(tempStuId)fmt.Println(*(tempStuId))fmt.Println("-----------接口---------")//接口var StuInterChain chan interface{}StuInterChain = make(chan interface{},10)stuInit:= Stu{name:"safly",}//存StuInterChain <- &stuInit//取mFetchStu:= <- StuInterChainfmt.Println(mFetchStu)//转var mStuConvert *StumStuConvert,ok := mFetchStu.(*Stu)if !ok{fmt.Println("cannot convert")return}fmt.Println(mStuConvert)fmt.Println(*(mStuConvert))}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
10
--------/map类型---------
map[stu03:003 stu01:001 stu02:002]
--------结构体---------
{safly}
--------结构体内存地址---------
&{safly}
{safly}
-----------接口---------
&{safly}
&{safly}
{safly}
PS E:\golang\go_pro\src\safly>

开启goroute,实现chan之间的同步存取

package mainimport ("time""fmt"
)func main() {intChan := make(chan int,5)go write(intChan)go read(intChan)time.Sleep(10 *time.Second)
}/*
由于管道容量是5,开启go写入10个数据,再写入5个数据,
会阻塞,
然而read每秒会读取一个,然后在会写入一个数据*/
func write(ch chan int){for i:= 0;i<10;i++{ch <- ifmt.Println("put data:",i)}
}func read(ch chan int){for{var b intb = <- chfmt.Println(b)time.Sleep(time.Second)}
}

测试输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
put data: 0
put data: 1
put data: 2
put data: 3
put data: 4
put data: 5
0
1
put data: 6
2
put data: 7
3
put data: 8
4
put data: 9
5
6
7
8
9
PS E:\golang\go_pro\src\safly>

channel关闭

channel关闭后,就不能取出数据了

package mainimport "fmt"func main() {var ch chan intch = make(chan int, 5)for i := 0; i < 5; i++ {ch <- i}close(ch)for {var b intb, ok := <-chif ok == false {fmt.Println("chan is close")break}fmt.Println(b)}
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
0
1
2
3
4
chan is close
PS E:\golang\go_pro\src\safly>

如果将close(ch)注释掉,意思是不关闭管道,那么会出现dead lock死锁
因为存入管道5个数字,然后无限取数据,会出现死锁

range

package mainimport "fmt"func main() {var ch chan intch = make(chan int, 10)for i := 0; i < 10; i++ {ch <- i}close(ch)for v := range ch {fmt.Println(v)}
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
0
1
2
3
4
5
6
7
8
9
PS E:\golang\go_pro\src\safly>

同样如果将close(ch)注释掉,意思是不关闭管道,那么会出现dead lock死锁
因为存入管道10个数字,然后无限取数据,在取出来第10个数据,在次range管道,会dead lock

单元测试
  1. 文件名必须以_test.go结尾
  2. 使用go test执行单元测试

这里写图片描述

calc.go

package mainfunc add(a, b int) int {return a + b
}func sub(a, b int) int {return a - b
}

calc_test.go

package mainimport ("testing"
)func TestAdd(t *testing.T) {r := add(2, 4)if r != 6 {t.Fatalf("add(2, 4) error, expect:%d, actual:%d", 6, r)}t.Logf("test add succ")
}

来执行test测试如下:

版权所有 (C) 2016 Microsoft Corporation。保留所有权利。PS E:\golang\go_pro> cd src
PS E:\golang\go_pro\src> cd safly
PS E:\golang\go_pro\src\safly> cd test
PS E:\golang\go_pro\src\safly\test> go test
PASS
ok      safly/test      0.053s

这篇关于golang基础-goroutine初识、chan存取、goroutine和chan相结合、关闭chan、range取、单元测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125217

相关文章

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

sysmain服务可以禁用吗? 电脑sysmain服务关闭后的影响与操作指南

《sysmain服务可以禁用吗?电脑sysmain服务关闭后的影响与操作指南》在Windows系统中,SysMain服务(原名Superfetch)作为一个旨在提升系统性能的关键组件,一直备受用户关... 在使用 Windows 系统时,有时候真有点像在「开盲盒」。全新安装系统后的「默认设置」,往往并不尽编

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Python WebSockets 库从基础到实战使用举例

《PythonWebSockets库从基础到实战使用举例》WebSocket是一种全双工、持久化的网络通信协议,适用于需要低延迟的应用,如实时聊天、股票行情推送、在线协作、多人游戏等,本文给大家介... 目录1. 引言2. 为什么使用 WebSocket?3. 安装 WebSockets 库4. 使用 We

从基础到高阶详解Python多态实战应用指南

《从基础到高阶详解Python多态实战应用指南》这篇文章主要从基础到高阶为大家详细介绍Python中多态的相关应用与技巧,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、多态的本质:python的“鸭子类型”哲学二、多态的三大实战场景场景1:数据处理管道——统一处理不同数据格式

MySQL数据类型与表操作全指南( 从基础到高级实践)

《MySQL数据类型与表操作全指南(从基础到高级实践)》本文详解MySQL数据类型分类(数值、日期/时间、字符串)及表操作(创建、修改、维护),涵盖优化技巧如数据类型选择、备份、分区,强调规范设计与... 目录mysql数据类型详解数值类型日期时间类型字符串类型表操作全解析创建表修改表结构添加列修改列删除列

Python 函数详解:从基础语法到高级使用技巧

《Python函数详解:从基础语法到高级使用技巧》本文基于实例代码,全面讲解Python函数的定义、参数传递、变量作用域及类型标注等知识点,帮助初学者快速掌握函数的使用技巧,感兴趣的朋友跟随小编一起... 目录一、函数的基本概念与作用二、函数的定义与调用1. 无参函数2. 带参函数3. 带返回值的函数4.

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

全面解析Golang 中的 Gorilla CORS 中间件正确用法

《全面解析Golang中的GorillaCORS中间件正确用法》Golang中使用gorilla/mux路由器配合rs/cors中间件库可以优雅地解决这个问题,然而,很多人刚开始使用时会遇到配... 目录如何让 golang 中的 Gorilla CORS 中间件正确工作一、基础依赖二、错误用法(很多人一开