20、单元测试
推荐使用TDD(Test Driver Development),然而现在很多人都不注重测试。
go test工具Go语言中依赖go test命令。编写测试代码和编写普通的Go代码过程是类似的。
go test命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内,所有以_test.go为后缀的源代码文件都是go test测试的一部分,不会被go build编译到最终可执行文件。
在*_go test文件中有三种类型的函数,单元测试函数,基准测试函数和实力函数。
类型
格式
作用
测试函数
函数名前缀为Test
测试程序的一些逻辑行为是否正确
基准函数
函数名前缀为Benchmark
测试函数的性能
示例函数
函数名前缀为Example
为文档提供示例文档
go test命令会遍历所有的*_test.go文件中符合上述命名规则的函数,然后生成一个临时的main包用于调用相应的测试函数,然后构建并运行,报告测试结果,最后清理测试中生成的临时文件。
测试函数测试函数的格式每个测试函数必须导入testing包,测试函数的基本格式(签名)如下。
123func T ...
19、网络编程
网络协议介绍互联网的核心是一系列的协议,总称为互联网协议,这些协议规定了电脑如何连接和组成网络。
互联网分层模型互联网的逻辑实现被分为好几层,每一层都有自己的功能。
Socket编程Socket是BSD UNIX的进程通信机制,也称作套接字,用于描述IP地址和端口,是一个通信链的句柄。Socket可以理解为TCP/IP网络的API,它定义了许多函数或例程,可以使用它他们开发TCP/IP网络上的应用程序。
socket图解Socket是应用层与TCP/IP协议族通信的中间软件抽象层。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket后面,对用户来说只需要调用Socket规定的相关函数,让Socket去组织符合指定的协议数据然后进行通信。
Go语言实现TCP通信TCP协议TCP/IP(Transmission Controller Protocol/Internet Protocol)即传输控制协议/网间协议,是一种面向连接(连接导向)的,可靠的,基于字节流的传输层(Transport layer)通信协议,因为是面向连接的协议,数据像水流一 ...
19、并发编程
1、并发与并行并发:同一时间段内执行多个人任务。
并行:同一时刻执行多个任务。
go语言中并发通过goroutine实现。goroutine雷系线程,属于用户态的线程,我们可以根据需要创建成千上万的goroutine并发工作。goroutine是由Go语言的运行时runtime调度完,而先线程是由操作系统调度完成。
Go语言还提供channel在多个goroutine进行通信。goroutine和channel是Go语言秉承的CSP(Communicating Sequential Process)并发模式的实现基础。
2、goroutine在java/c++中我们要实现并发编程的时候,我们为您通常需要维护一个线程池,并且需要自己包装一个有一个的任务,同时需要自己去调度线程执行任务并维护上线纹切换。
Go语言中的goroutine就是这种机制,goroutine的概念类似线程,但goroutine是由Go语言运行时runtime调度和管理的。Go程序会智能的将goroutine中的任务合理的分配给每个CPU。Go语言之所以称为现代化的编程语言,就是因为它在语言层面上已经实现了调度和上下 ...
18、strconv
string与int类型转换Atoi()1func Atoi(s string) (i int, err error)
12345678910//字符串类型的整数转换为int类型func atoi(){ s1 := "100" i, err := strconv.Atoi(s1) if err != nil { fmt.Println("can't convent to int") }else { fmt.Printf("type: %T value: %#v\n", i, i) }}
Itoa()1func Itoa(i int) string
123456//int转字符串func itoa(){ s1 := 100 itoa := strconv.Itoa(s1) fmt.Printf("type: %T value: %#v\n", itoa, itoa) ...
17、反射
变量的内在机制Go语言中的变量是分为两部分的:
类型信息:预先定义好的元信息。
值信息:程序运行过程中可动态变化的。
反射介绍反射是指载程序运行期间对程序本身进行访问和修改的能力。程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分。在程序运行时,程序无法获取自身信息。
支持反射的语言可以在程序编译期将变量的反射信息,如字段,类型信息,结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,并且有能力修改他们。
Go语言使用reflect包方访问程序的反射信息。
reflect包在Go语言反射机制中,任何接口值都是由一个具体类型和具体类型的值两部分组成的。在Go语言的反射的相关功能是由内置的reflect包提供,任意接口值在反射中都可以理解为由reflect.Type和reflect.Value两部分组成,并且reflect包提供了reflect.TypeOf()和reflect.ValueOf()两个函数来获取任意对象的Value和Type。
TypeOf在Go语言中,使用reflect.TypeOf()函数可以获取任意值的类型对象(reflect.Typ ...
16、time
time包提供了时间显示和测量的函数。日历计算采用的是公历。
时间类型time.Time类型表示时间。我们可以通过time.Now()函数获取当前时间的对象,然受获取时间对象的年月日时分秒等信息。
12345678910111213//时间类型func timeDemo(){ now := time.Now() fmt.Printf("current time:%v\n", now) year := now.Year() //年 month := now.Month() //月 day := now.Day() //日 hour := now.Hour() //时 minute := now.Minute() //分 second := now.Second() //秒 fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)}
时间戳时间戳是自19 ...
15、文件
打开和关闭文件os.Open()函数能够打开一个文件,返回一个*file和一个err。对得到的文件调用Close文件能够关闭文件。
12345678910func readFromByIO(){ //打开文件 fileObj, err := os.Open("./main.go") if err != nil{ fmt.Print("open file failed, err :%v", err) return } //关闭文件流 defer fileObj.Close()}
为防止文件忘记关闭,我们通常使用defer注册文件关闭语句。
读取文件基本使用1func (f *file) Read(b [byte]) (n int, err error)
他接受一个字节切片,返回读取的字节数组和可能的具体错误,读到文件末尾时会返回0和io.EOF
12345678910111213141516171819202122232425262728func readFro ...
14、包
在工程化的Go语言开发项目中,Go语言的源码是建立在包(package)基础之上的。
Go语言的包(package)1、包介绍包(package)是多个Go源码的集合,是一种高级的代码复用方案,Go语言为我们提供了很多的内志包,如fmt,os,io等。
2、定义包我们可以根据自己的需求创建自己的包。一个包可以理解为一个存放.go文件的文件夹。该文件夹下的所有go文件都要在第一行添加如下代码,声明该文件归属的包。
1package 包名
注意事项:
一个文件夹下面直接包含的文件只能归属于同一个poackage,同样一个package的文件不能在多个文件夹下。
包名可以不和文件夹的名字一样,包名不得包含-符号。
包名为main的包为应用程序的入口包,这种包编译后会得到一个可执行文件,而编译不包含main包的源代码则不会得到可执行文件。
3、可见性如果想在一个包中引用另一个包的标识符(如变量,常量,类型,函数等)时,该标识符必须是对外可见的(public)。在Go语言中只需要将标识符首字母大写就能让标识符对外可见了。
4、包的导入在代码中引用其他包的内容,需要使用import关键字导入 ...
13、interface
接口(interface)定义了一个对象的行为规范,之定义规范不实现。
接口类型Go语言中接口(interface)是一种类型,一种抽象的类型。
interface是一组method的集合,是duck-type programming的一种体现。接口做的事情就像是定一个协议(规则)。不关心属性(数据),只关心行为方法。
接口的定义12345type 接口类型名 interface{ 方法1(参数1, 参数2...) (返回值1, 返回值2...) 方法2(参数1, 参数2...) (返回值1, 返回值2...) ...}
其中:
接口名:使用type将接口定义为自定义类型名时。Go语言在接口命名时,一般会在单词后面加er,如有写操作的接口叫做Writer,有字符串功能的接口叫做stringer。接口名最好能突出该接口类型的含义。
方法名:当方法名首字母是大写并且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码当问。
参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以省略。
123type wr ...
12、结构体
类型别名和自定义类型自定义类型Go语言中有一些的基本的数据类型,例如string,整型,浮点型,布尔等数据类型。
Go语言中可以使用type关键字来定义自己的类型。
自定义类型是定义了一个全新的类型。可以基于内置的基本数据类型进行定义,也可以通过struct定义。
1234567//自定义类型type myInt int//自定义类型var a myInta = 100fmt.Printf("myInt类型是%T, 值为%d\n", a, a)//myInt类型是main.myInt, 值为100
类型别名TypeAlias只是Type的类型名字的别称,本质上TypeAlias 的类型与 Type类型是同一个类型。
12//类型别名type TypeAlias = Type
rune和byte就是类型别名
12type byte = uint8type rune = int32
1234567//类型别名type TypeAlias = int//类型别名var b TypeAliasb = 100fmt.Printf("myInt类型是%T, 值为 ...