Go工具命令使用

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


浏览器查看

效果