Go语言进阶 | 青训营笔记

83 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

进阶与依赖管理

进阶

  1. 协程-goroutine
  • Go 的 Goroutine 是用户态的,其协程栈占用仅有 KB 级别,十分节约系统资源;Goroutine 是有栈协程
  • 提倡通过channel 同步内存
  • 当主协程在停止后,其他子协程将会一同停止
  • 可以通过WaitGroup对主协程进行控制以实现主协程的阻塞等待其他协程结束后再结束。
  1. 通道-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

引用

该文章部分内容来自于以下课程或网页: