这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
进阶与依赖管理
进阶
- 协程-goroutine
- Go 的 Goroutine 是用户态的,其协程栈占用仅有 KB 级别,十分节约系统资源;Goroutine 是有栈协程。
- 提倡通过channel 同步内存
- 当主协程在停止后,其他子协程将会一同停止
- 可以通过WaitGroup对主协程进行控制以实现主协程的阻塞等待其他协程结束后再结束。
- 通道-channel
- 通道的定义:无缓冲通道
ch = make(chan int),有缓冲通道ch = make(chan int,2) - 通道的赋值:向通道中输出
ch <- v,从通道中读出v <- ch - 通道的关闭:
close(ch)
依赖管理
在各种语言中,作为编写程序的基础,依赖管理属于较为主要且基础的一部分。对于 Go 的依赖管理来说,经历了 GOPATH,Go Vender,Go Module 三个过程,这里着重介绍go Module。
go mod
- 层次结构 仓库->Module->Package
- 相关文件存储位置
go install命令安装二进制到$GOBIN目录,其默认位置为$GOPATH/bin。 go get命令缓存下载的Modules到$GOMODCACHE目录,默认位置为$GOPATH/pkg/mod。 go get命令缓存下载的checksum数据到$GOPATH/pkg/sumdb目录。 - 实验过程 新建一个文件:hello.go
package hello
func Hello() string {
return "Hello, world."
}
创建对应的测试函数hello_test.go
package hello
import "testing"
func TestHello(t *testing.T) {
want := "Hello world"
if get := Hello(); get != want {
t.Errorf("Hello() = %q, want = %q",get,want)
}
}
使用test命令测试,会提示未找到go.mod文件
> go test
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
接着初始化使用go mod init hello初始化go.mod,其中包含一个package hello
> go mod init hello
go: creating new go.mod: module hello
go: to add module requirements and sums:
go mod tidy
1 package hello
> cat go.mod
module hello
go 1.19
初始化后,可以进行测试
> go test
--- FAIL: TestHello (0.00s)
hello_test.go:6: Hello() = "Hello world!", want = "Hello world"
FAIL
exit status 1
FAIL hello 1.677s
在hello.go中加入依赖,进行实验
package hello
import "rsc.io/quote"
func Hello() string {
return quote.Hello()
}
测试时发现没有添加对应的依赖使用go get添加。
> go test
hello.go:2:8: no required module provides package rsc.io/quote; to add it:
go get rsc.io/quote
> go get rsc.io/quote
> cat go.mod
module hello
go 1.19
require (
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
rsc.io/quote v1.5.2 // indirect
rsc.io/sampler v1.3.0 // indirect
)
在go.mod的目录下自动生成了go.sum文件,存储了依赖的哈希值,以保证依赖代码的一致性
> cat go.sum
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
测试
单元测试
- 测试文件命名格式:xxx-test.go
- 测试函数命名格式:
func TestXxx(t *testing.T)再测试函数中首先初始化及数据装载,调用待测试函数进行测试,最后将释放资源 - 使用 go test 命令进行测试 IDE中会自动识别测试代码,调用测试相关指令进行测试
Mock 打桩
框架:monkry
- 为一个函数打桩
- 为一个方法打桩
基准测试
go test -bench=. -benchmem
引用
该文章部分内容来自于以下课程或网页:
- 字节内部课:Go 语言入门 - 工程实践
- Go语言的依赖解决方案:Go modules (csdn.net)
- Go语言重新开始,Go Modules的前世今生与基本使用-腾讯云开发者