go get #
go get命令——一键获取代码、编译并安装
go get 命令可以借助代码管理工具通过远程拉取或更新代码包及其依赖包,并自动完成编译和安装。整个过程就像安装一个 App 一样简单。
这个命令可以动态获取远程代码包,目前支持的有 BitBucket、GitHub、Google Code 和 Launchpad。在使用 go get 命令前,需要安装与远程包匹配的代码管理工具,如 Git、SVN、HG 等,参数中需要提供一个包名
go get github.com/cosmtrek/air
1、执行download到%GOPATH%/pkg下
2、执行安装命令,生成执行命令到%GOPATH%/bin下
go install github.com/cosmtrek/air
参数介绍:
- -d 只下载不安装
- -f 只有在你包含了 -u 参数的时候才有效,不让 -u 去验证 import 中的每一个都已经获取了,这对于本地 fork 的包特别有用
- -fix 在获取源码之后先运行 fix,然后再去做其他的事情
- -t 同时也下载需要为运行测试所需要的包
- -u 强制使用网络去更新包和它的依赖包
- -v 显示执行的命令
go build #
go build 命令主要用于编译代码。在包的编译过程中,若有必要,会同时编译与之相关联的包
go build -o test main.go ...[多个go文件]
参数介绍:
-
-gcflags: 传递给编译器的参数
-
-B 禁用边界检查
-
-N 禁用优化
-
-l 禁用函数内联
-
-u 禁用unsafe代码
-
-m 输出优化信息
-
-S 输出汇编代码
-
-
-ldflags: 传递给链接器的参数
-
-w 禁用DRAWF调试信息,但不包括符号表
-
-s 禁用符号表
-
-X 修改字符串符号值 -X main.VER ‘0.99’ -X main.S ‘abc’
-
-H 链接文件类型,其中包括windowsgui. cmd/ld/doc.go
-
-
-work: 查看编译临时目录
-
-race: 允许数据竞争检测(仅支持amd64)
-
-n: 查看但不执行编译指令
-
-x: 查看并执行编译命令
-
-a: 强制重新编译所有依赖包
-
-v: 查看被编译的包名,包括依赖包
-
-p n:并行编译所使用的CPU数,默认为全部
-
-o:输出文件名
更多参数可以通过
go tool compile -h
go tool link -h
env GOSSAFUNC=main go build main.go
设置环境变量会在本地目录下生成ssa.html文件
D:\study\src\example>env GOSSAFUNC=main go build main.go
# runtime
dumped SSA to D:\study\src\example\ssa.html
# command-line-arguments
dumped SSA to .\ssa.html
build标签使用
debug.go
package main
// +build debug
const debug = true
prod.go
package main
// +build !debug
const prod = true
main.go
package main
import "log"
func main() {
if debug {
log.Println("run debug")
} else {
log.Println("run prod")
}
}
go build -tags debug -o debug.exe //生成带有调试信息的可执行文件
go build -tags !debug -o prod.exe //生成发布的可执行文件
go clean #
go clean
命令可以移除当前源码包和关联源码包里面编译生成的文件
go clean -i -n
参数说明:
- -i 清除关联的安装的包和可运行文件,也就是通过
go install
安装的文件; - -n 把需要执行的清除命令打印出来,但是不执行,这样就可以很容易的知道底层是如何运行的;
- -r 循环的清除在 import 中引入的包;
- -x 打印出来执行的详细命令,其实就是 -n 打印的执行版本;
- -cache 删除所有
go build
命令的缓存 - -testcache 删除当前包所有的测试结果
go generate #
go generate 运行该命令时,它将扫描与当前包相关的源代码文件
使用该命令注意事项:
- 该特殊注释必须在 .go 源码文件中;
- 每个源码文件可以包含多个 generate 特殊注释;
- 运行
go generate
命令时,才会执行特殊注释后面的命令; - 当
go generate
命令执行出错时,将终止程序的运行; - 特殊注释必须以
//go:generate
开头,双斜线后面没有空格。
在下面这些场景下,我们会使用go generate
命令
- yacc:从 .y 文件生成 .go 文件;
- protobufs:从 protocol buffer 定义文件(.proto)生成 .pb.go 文件;
- Unicode:从 UnicodeData.txt 生成 Unicode 表;
- HTML:将 HTML 文件嵌入到 go 源码;
- bindata:将形如 JPEG 这样的文件转成 go 代码中的字节数组
再比如:
- string 方法:为类似枚举常量这样的类型生成 String() 方法;
- 宏:为既定的泛型包生成特定的实现,比如用于 ints 的 sort.Ints
go generate
命令格式如下所示:
go generate [-run regexp] [-n] [-v] [-x] [command] [build flags] [file.go... | packages]
参数说明:
- -run 正则表达式匹配命令行,仅执行匹配的命令;
- -v 输出被处理的包名和源文件名;
- -n 显示不执行命令;
- -x 显示并执行命令;
- command 可以是在环境变量 PATH 中的任何命令
package main
import "fmt"
//go:generate env GOSSAFUNC=main go run main.go
//go:generate go version
func main() {
fmt.Println("http://c.biancheng.net/golang/")
}
执行
go generate +x
自动生成String()方法
go get golang.org/x/tools/cmd/stringer
go tool pprof #
runtime/pprof
net/http/pprof
runtime.pprof 提供基础的运行时分析的驱动,但是这套接口使用起来还不是太方便,例如:
- 输出数据使用 io.Writer 接口,虽然扩展性很强,但是对于实际使用不够方便,不支持写入文件。
- 默认配置项较为复杂。
package main
import (
"fmt"
"os"
"runtime/pprof"
)
func main() {
fp,_ := os.Create("cpu.pprof")
err := pprof.StartCPUProfile(fp)
if err != nil {
panic(err)
}
test()
defer func() {
pprof.StopCPUProfile()
fp.Close()
}()
}
func test() {
fmt.Println("run test")
}
go build -o pp.exe main.go
D:\study\src\example>pp.exe
run test
D:\study\src\example>go tool pprof pp.exe cpu.pprof
File: pp.exe
Type: cpu
Time: Mar 20, 2022 at 3:28am (CST)
Duration: 1.18s, Total samples = 150ms (12.76%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 150ms, 100% of 150ms total
Showing top 10 nodes out of 33
flat flat% sum% cum cum%
80ms 53.33% 53.33% 80ms 53.33% runtime.stdcall3
20ms 13.33% 66.67% 20ms 13.33% runtime.stdcall6
10ms 6.67% 73.33% 10ms 6.67% runtime.(*consistentHeapStats).acquire
10ms 6.67% 80.00% 30ms 20.00% runtime.findrunnable
10ms 6.67% 86.67% 10ms 6.67% runtime.memmove
10ms 6.67% 93.33% 10ms 6.67% runtime.procyield
10ms 6.67% 100% 10ms 6.67% runtime.wakeNetPoller
0 0% 100% 10ms 6.67% main.joinSlice (inline)
0 0% 100% 10ms 6.67% main.main
0 0% 100% 90ms 60.00% runtime.(*pageAlloc).scavenge
(pprof)
很多第三方的包在系统包 runtime.pprof 的技术上进行便利性封装
go get github.com/pkg/profile
package main
import (
"fmt"
"github.com/pkg/profile"
)
func main() {
//profile.CpuProfile 为cpu占用情况
stopper := profile.Start(profile.MemProfile, profile.ProfilePath("."))
defer stopper.Stop()
test()
}
func test() {
fmt.Println("test run mem")
}
go build -o main.exe main.go
D:\study\src\example>main.exe
2022/03/20 03:44:44 profile: memory profiling enabled (rate 4096), mem.pprof
test run mem
2022/03/20 03:44:44 profile: memory profiling disabled, mem.pprof
D:\study\src\example>go tool pprof main.exe mem.pprof
File: main.exe
Type: inuse_space
Time: Mar 20, 2022 at 3:44am (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 5.23kB, 100% of 5.23kB total
flat flat% sum% cum cum%
5.23kB 100% 100% 5.23kB 100% compress/flate.(*huffmanEncoder).generate
0 0% 100% 5.23kB 100% compress/flate.init.0
0 0% 100% 5.23kB 100% runtime.doInit
0 0% 100% 5.23kB 100% runtime.main
(pprof)
go tool trace #
package main
import (
"fmt"
"io/ioutil"
"os"
"runtime"
"runtime/trace"
"time"
)
func main() {
_ = runtime.StartTrace()
go func() {
for {
data := runtime.ReadTrace()
if data == nil {
break
}
_ = ioutil.WriteFile("trace1.out", data, 0755)
}
}()
time.Sleep(time.Second * 10)
test()
defer runtime.StopTrace()
}
也可以使用runtime.trace直接写
f, err := os.Create("trace.out")
if err != nil {
panic(err)
}
defer f.Close()
err = trace.Start(f)
if err != nil {
panic(err)
}
defer trace.Stop()
test()
go build -o trace.exe trace.go
D:\study\src\example>trace.exe
test run trace
D:\study\src\example>go tool trace trace.out
2022/03/20 04:15:45 Parsing trace...
2022/03/20 04:15:45 Splitting trace...
2022/03/20 04:15:45 Opening browser. Trace viewer is listening on http://127.0.0.1:49939
浏览器查看