一、编译(go build)
1、go build无参数编译
两个文件在同一个文件夹(gobuild)
main.go代码如下:
package main
import (
"fmt"
)
func main() {
pkgFunc()
fmt.Println("hello worlds")
}
lib.go代码如下:
package main
import (
"fmt"
)
func pkgFunc() {
fmt.Println("call pakFunc")
}
输入命令行如下:
go build
输入命令行如下:
ls
运行结果如下:
gobuild lib.go main.go
输入命令行如下:
./gobuild
运行结果如下:
call pakFunc
hello worlds
2、go build+文件列表
格式如下:
go build file1.go file2.go……
代码如下:
$ go build main.go lib.go
$ ls
lib.go main main.go
$ ./main
call pkgFunc
hello world
$ go build lib.go main.go
$ ls
lib lib.go main main.go
如果需要指定输出可执行文件名,可以使用-o参数,参见下面的例子:
$ go build -o myexec main.go lib.go
$ ls
lib.go main.go myexec
$ ./myexec
call pkgFunc
hello world
上面代码中,在go build和文件列表之间插入了-o myexec参数,表示指定输出文件名为myexec。
3、go build+包
一个文件夹(goinstall)里有一个文件(main.go)和一个文件夹(mypkg)。一个文件夹(mypkg)里有一个文件(mypkg.go)。
main.go代码如下:
package main
import (
"fmt"
"test/goinstall/mypkg"
)
func main() {
mypkg.CustomPkgFunc()
fmt.Println("hello world")
}
mypkg.go代码如下:
package mypkg
import "fmt"
func CustomPkgFunc() {
fmt.Println("call CustomPkgFunc")
}
执行以下命令将按包方式编译goinstall代码:
douxiaobodeMac-mini:goinstall douxiaobo$ go build -o main test/goinstall
douxiaobodeMac-mini:goinstall douxiaobo$ ls
main main.go mypkg
douxiaobodeMac-mini:goinstall douxiaobo$ ./main
call CustomPkgFunc
hello world
4、go build编译时的附加参数
附加参数 | 备注 |
-v | 编译时显示包名 |
-p n | 开启并发编译,默认有情况下该值为CPU逻辑核数 |
-a | 强制重新构建 |
-n | 打印编译时会用到的所有命令,但不真正执行 |
-x | 打印编译时会用到的所有命令 |
-race | 开启竞态检测 |
二、编译后运行(go run)
代码如下:
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("args:", os.Args)
}
运行结果如下:
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go run main.go --filename xxx.go
args: [C:\Users\A-XIAO~1\AppData\Local\Temp\go-build69443624\b001\exe\main.exe --filename xxx.go]
三、编译并安装(go install)
四、一键获取代码、编译并安装(go get)
1、远程包的路径格式
网站域名/作者或机构/项目名
2、go get + 远程包
默认情况下,go get可以直接使用。
3、go get使用时的附加参数
附加参数 | 备注 |
-v | 显示操作流程的日志及信息,方便检查错误 |
-u | 下载丢失的包,但不会更新已经存在的包 |
-d | 只下载,不安装 |
-insecure | 允许使用 |
五、测试(go test)
1、单元测试——测试和验证代码的框架
func TestXXX( t *testing.T)
helloworld_test.go的代码如下:
package go_test
import "testing"
func TestHelloWorld(t *testing.T) {
t.Log("Hello world")
}
1)单元测试命令行
运行结果如下:
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go test helloworld_test.go
ok command-line-arguments 0.373s
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go test -v helloworld_test.go
=== RUN TestHelloWorld
helloworld_test.go:6: Hello world
--- PASS: TestHelloWorld (0.00s)
PASS
ok command-line-arguments 0.261s
2)运行指定单元测试用例
代码如下:
package go_test
import "testing"
func TestA(t *testing.T) {
t.Log("A")
}
func TestAK(t *testing.T) {
t.Log("AK")
}
func TestB(t *testing.T) {
t.Log("B")
}
func TestC(t *testing.T) {
t.Log("C")
}
运行结果如下:
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go test -v -run TestA select_test.go
=== RUN TestA
select_test.go:6: A
--- PASS: TestA (0.00s)
=== RUN TestAK
select_test.go:10: AK
--- PASS: TestAK (0.00s)
PASS
ok command-line-arguments 0.308s
3)标记单元测试结果
代码如下:
package go_test
import (
"fmt"
"testing"
)
func TestFailNow(t *testing.T) {
t.FailNow()
}
func TestFail(t *testing.T) {
fmt.Println("before fail")
t.Fail()
fmt.Println("after fail")
}
运行结果如下:
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go test -v fail_test.go
=== RUN TestFailNow
--- FAIL: TestFailNow (0.00s)
=== RUN TestFail
before fail
after fail
--- FAIL: TestFail (0.00s)
FAIL
FAIL command-line-arguments 0.261s
FAIL
4)单元测试日志
方法 | 备注 |
Log | 打印日志,同时结束测试 |
Logf | 格式化打印日志,同时结束测试 |
Error | 打印错误日志,同时结束测试 |
Errorf | 格式化打印错误日志,同时结束测试 |
Fatal | 打印致命日志,同时结束测试 |
Fatalf | 格式化打印致命日志,同时结束测试。 |
2、基准测试——获得代码内存占用和运行效率的性能数据
1)基础测试基本使用
代码如下:
package go_test
import "testing"
func Benchmark_Add(b *testing.B) {
var n int
for i := 0; i < b.N; i++ {
n++
}
}
运行结果如下:
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go test -v -bench="." benchmark_test.go
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i7-7660U CPU @ 2.50GHz
Benchmark_Add
Benchmark_Add-4 1000000000 0.4225 ns/op
PASS
ok command-line-arguments 0.728s
在Linux和Mac,go test -v -bench=. benchmark_test.go
在Windows下使用go test命令行时,-bench=.应写为-bench="."。
2)基准测试原理
3)自定义测试时间
运行结果如下:
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go test -v -bench="." -benchtime=5s benchmark_test.go
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i7-7660U CPU @ 2.50GHz
Benchmark_Add
Benchmark_Add-4 1000000000 0.2612 ns/op
PASS
ok command-line-arguments 0.546s
4)测试内存
代码如下:
package go_test
import "testing"
func Benchmark_Alloc(b *testing.B) {
for i := 0; i < b.N; i++ {
fmt.Sprintf("%d", i)
}
}
运行结果如下:
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go test -v -bench=Alloc -benchmen benchmark_test.go
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
5)控制计时器
代码如下:
package go_test
import "testing"
func Benchmark_Add_TimerControl(b *testing.B) {
//重置计时器
b.ResetTimer()
//停止计时器
b.StopTimer()
//开始计时器
b.StartTimer()
var n int
for i := 0; i < b.N; i++ {
n++
}
}
六、性能分析(go pprof)——发现代码性能问题的调用位置
1、安装第三方图形化显示分析数据工具(Graphviz)
www . graphviz . org
CentOS下,可以使用yum指令直接安装:
yum install graphiviz
2、安装第三方性能分析来分析代码包
go get github.com/pkg/profile
3、性能分析代码
基准测试:cup.go,代码如下:
package main
import (
"time"
"github.com/pkg/profile"
)
func joinSlice() []string {
var arr []string
for i := 0; i < 10000; i++ {
//故意造成很多次的切片添加(append)操作,由于每次操作可有会有内存重新分配和移动,性能较低
arr = append(arr, "arr")
}
return arr
}
func main() {
//开始性能分析,返回一个停止接口
stopper := profile.Start(profile.CPUProfile, profile.ProfilePath("."))
//在main()结束时停止性能分析
defer stopper.Stop()
//分析的核心逻辑
joinSlice()
//让程序至少运行1秒
time.Sleep(time.Second)
}
书上说:
$ go build -o cpu cpu.go
$ ./cup
$ go tool pprof --pdf cup cup.pprof > cup.pdf
func joinSlice() []string {
const count = 100000
var arr []string = make([]string, count)
for i := 0; i < count; i++ {
arr[i] = "arr"
}
return arr
}