Go工具简介-您将在处理 Go 项目时变得更有效率,并快速可靠地执行常见任务。

Q shen 2023-06-05 17:09:14

“我的Go+语言初体验” | 征文活动进行中......

Go工具概述

工具通常被认为是 Go 生态系统的强大方面之一。该go命令是通往本文中将要讨论的许多工具的入口。

通过了解这里讨论的每个工具,您将在处理 Go 项目时变得更有效率,并快速可靠地执行常见任务。

查看环境变量

go env命令用于显示有关当前 Go 环境的信息。
这是此命令输出的示例:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">GO111MODULE</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"on"</span>
<span style="color:var(--syntax-text-color)">GOARCH</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"amd64"</span>
<span style="color:var(--syntax-text-color)">GOBIN</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"/home/ayo/go/bin"</span>
<span style="color:var(--syntax-text-color)">GOCACHE</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"/home/ayo/.cache/go-build"</span>
<span style="color:var(--syntax-text-color)">GOENV</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"/home/ayo/.config/go/env"</span>
<span style="color:var(--syntax-text-color)">GOEXE</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">""</span>
<span style="color:var(--syntax-text-color)">GOFLAGS</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">""</span>
<span style="color:var(--syntax-text-color)">GOHOSTARCH</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"amd64"</span>
<span style="color:var(--syntax-text-color)">GOHOSTOS</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"linux"</span>
<span style="color:var(--syntax-text-color)">GOINSECURE</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">""</span>
<span style="color:var(--syntax-text-color)">GONOPROXY</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">""</span>
<span style="color:var(--syntax-text-color)">GONOSUMDB</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">""</span>
<span style="color:var(--syntax-text-color)">GOOS</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"linux"</span>
<span style="color:var(--syntax-text-color)">GOPATH</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"/home/ayo/go"</span>
<span style="color:var(--syntax-text-color)">GOPRIVATE</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">""</span>
<span style="color:var(--syntax-text-color)">GOPROXY</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"https://proxy.golang.org,direct"</span>
<span style="color:var(--syntax-text-color)">GOROOT</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"/usr/lib/go"</span>
<span style="color:var(--syntax-text-color)">GOSUMDB</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"sum.golang.org"</span>
<span style="color:var(--syntax-text-color)">GOTMPDIR</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">""</span>
<span style="color:var(--syntax-text-color)">GOTOOLDIR</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"/usr/lib/go/pkg/tool/linux_amd64"</span>
<span style="color:var(--syntax-text-color)">GCCGO</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"gccgo"</span>
<span style="color:var(--syntax-text-color)">AR</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"ar"</span>
<span style="color:var(--syntax-text-color)">CC</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"gcc"</span>
<span style="color:var(--syntax-text-color)">CXX</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"g++"</span>
<span style="color:var(--syntax-text-color)">CGO_ENABLED</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"1"</span>
<span style="color:var(--syntax-text-color)">GOMOD</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"/dev/null"</span>
<span style="color:var(--syntax-text-color)">CGO_CFLAGS</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"-g -O2"</span>
<span style="color:var(--syntax-text-color)">CGO_CPPFLAGS</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">""</span>
<span style="color:var(--syntax-text-color)">CGO_CXXFLAGS</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"-g -O2"</span>
<span style="color:var(--syntax-text-color)">CGO_FFLAGS</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"-g -O2"</span>
<span style="color:var(--syntax-text-color)">CGO_LDFLAGS</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"-g -O2"</span>
<span style="color:var(--syntax-text-color)">PKG_CONFIG</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"pkg-config"</span>
<span style="color:var(--syntax-text-color)">GOGCCFLAGS</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">"-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build145204762=/tmp/go-build -gno-record-gcc-switches"</span>
</code></span></span>

 

如果要查看特定变量的值,可以将它们作为参数传递给命令go env

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">env </span>GOPATH GOROOT GOBIN
/home/ayo/go
/usr/lib/go
/home/ayo/go/bin
</code></span></span>

 

可以使用以下命令访问每个变量的文档:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>go <span style="color:var(--syntax-text-color)">help </span>environmental
</code></span></span>

 

使用 go run 运行代码

假设您有一个main.go包含以下代码的文件,

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">package</span> <span style="color:var(--syntax-text-color)">main</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-string-color)">"fmt"</span>
<span style="color:var(--syntax-declaration-color)">func</span> <span style="color:var(--syntax-text-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-text-color)">fmt</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">Println</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Welcome to Go!"</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

 

您可以使用命令运行它go run,正如我们在本系列中多次看到的那样:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go run main.go
Welcome to Go!
</code></span></span>

 

go run命令编译程序,在您的/tmp目录中创建一个可执行文件,并一步执行此二进制文件。如果你想一次执行多个文件,你可以将它们全部作为参数传递给go run

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go run main.go time.go input.go
</code></span></span>

 

或者您可以使用通配符:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go run <span style="color:var(--syntax-declaration-color)">*</span>.go
</code></span></span>

 

从 Go v1.11 开始,您还可以一次运行整个包:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go run ./foo <span style="color:var(--syntax-comment-color)"># Run the package in the `foo` directory</span>
<span style="color:var(--syntax-text-color)">$ </span>go run <span style="color:var(--syntax-text-color)">.</span>     <span style="color:var(--syntax-comment-color)"># Run the package in the current directory</span>
</code></span></span>

 

使用 gofmt 格式化代码

如果你编写 Go 代码已经有很长时间了,你就会知道代码的格式有严格的约定。命令gofmt是对所有存在的 Go 代码强制执行这些约定的东西。

上一节中显示的代码片段格式不正确,因此让我们将其格式化为gofmt,如下所示:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>gofmt main.go
package main

import <span style="color:var(--syntax-string-color)">"fmt"</span>

func main<span style="color:var(--syntax-error-color)">()</span> <span style="color:var(--syntax-error-color)">{</span> fmt.Println<span style="color:var(--syntax-error-color)">(</span><span style="color:var(--syntax-string-color)">"Welcome to Go!"</span><span style="color:var(--syntax-error-color)">)</span> <span style="color:var(--syntax-error-color)">}</span>
</code></span></span>

 

这会格式化源文件中的代码并将结果打印到标准输出。如果你想用格式化的输出覆盖源文件,你需要添加标志-w

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>gofmt <span style="color:var(--syntax-error-color)">-w</span> main.go
</code></span></span>

 

要递归地格式化 Go 源文件(当前目录和子目录),
请将 a.指定为gofmt.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>gofmt <span style="color:var(--syntax-text-color)">.</span>
</code></span></span>

 

修复导入语句

在您可以在代码中使用包之前,您需要导入它。如果不这样做,代码将不会编译,并会显示错误。在您的文件中给出以下代码main.go

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">package</span> <span style="color:var(--syntax-text-color)">main</span>

<span style="color:var(--syntax-declaration-color)">func</span> <span style="color:var(--syntax-text-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">fmt</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">Println</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Welcome to Go!"</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

 

如果您尝试执行该程序,您应该会看到以下错误:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go run main.go
<span style="color:var(--syntax-comment-color)"># command-line-arguments</span>
./main.go:4:2: undefined: <span style="color:var(--syntax-text-color)">fmt</span>
</code></span></span>

 

在代码可以编译之前,fmt必须导入包。您可以手动添加必要的代码或使用goimports命令,它会为您添加必要的导入语句。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>goimports main.go
package main

import <span style="color:var(--syntax-string-color)">"fmt"</span>

func main<span style="color:var(--syntax-error-color)">()</span> <span style="color:var(--syntax-error-color)">{</span>
    fmt.Println<span style="color:var(--syntax-error-color)">(</span><span style="color:var(--syntax-string-color)">"Welcome to Go!"</span><span style="color:var(--syntax-error-color)">)</span>
<span style="color:var(--syntax-error-color)">}</span>
</code></span></span>

 

该命令还会删除所有不再引用的导入包,并以与gofmt. 因此,您也可以将goimports其视为gofmt.

goimports如果您将编辑器设置为在保存 Go 源文件时运行它,它的价值就会变得显而易见。这样,您就无需担心在使用包之前导入包或导入不再需要的语句。保存文件后,它会自动为您完成。大多数代码编辑器都有某种插件或设置可以帮助解决这个问题。

建立你的项目

要为您的程序构建可执行二进制文件,请使用go build命令。这将在当前目录中输出一个二进制文件:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go build
<span style="color:var(--syntax-text-color)">$ </span>./demo
Welcome to Go!
</code></span></span>

 

生成的二进制文件go build特定于您的操作系统架构,它包含运行该程序所需的一切。因此,你可以将它转移到另一台具有相同架构的机器上,即使没有安装 Go,它也会以同样的方式运行。

GOOS如果您想为您自己以外的体系结构交叉编译二进制文件,您需要做的就是在运行命令之前更改和GOARCH环境变量的值go build

例如,以下命令可用于为 64 位 Windows 机器生成二进制文件:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ GOOS</span><span style="color:var(--syntax-error-color)">=</span>windows <span style="color:var(--syntax-text-color)">GOARCH</span><span style="color:var(--syntax-error-color)">=</span>amd64 go build
</code></span></span>

 

要针对 Linux、macOS、ARM、Web Assembly 或其他目标进行编译,请参阅Go 文档以查看可用的GOOS和 的组合。GOARCH

安装 Go 二进制文件

如果您希望能够从其源目录之外运行该程序,则该go install命令是替代方法。go build

假设您的main.go文件位于名为 的目录中demo,以下命令将demo在您的$GOPATH/bin目录中创建一个二进制文件。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">install</span>
</code></span></span>

 

应该$GOPATH$HOME/go大多数计算机上。您可以使用以下命令检查它
go env

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">env </span>GOPATH
/home/ayo/go
</code></span></span>

 

如果您列出 的内容$GOPATH/bin,您应该会看到一个demo二进制文件:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span><span style="color:var(--syntax-text-color)">ls</span> <span style="color:var(--syntax-text-color)">$GOPATH</span>/bin
demo
</code></span></span>

 

可以通过demo从文件系统上的任何位置运行命令来执行此二进制文件。只要该$GOPATH/bin目录已添加到您的$PATH.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>demo
Welcome to Go!
</code></span></span>

 

列出包裹信息

默认调用go list返回您当前所在目录的导入路径名称或提供的包路径:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go list
github.com/ayoisaiah/demo
<span style="color:var(--syntax-text-color)">$ </span>go list github.com/joho/godotenv
github.com/joho/godotenv
</code></span></span>

 

go list我们可以使用标志自定义命令的输出-f,它允许您执行可以访问 Go 工具内部数据结构的 Go 模板。fmt例如,您可以使用以下命令列出名称:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go list <span style="color:var(--syntax-error-color)">-f</span> <span style="color:var(--syntax-string-color)">"{{ .Name }}"</span> <span style="color:var(--syntax-text-color)">fmt
fmt</span>
</code></span></span>

 

这本身并不是很有趣,但还有更多。您可以使用模板打印包的所有依赖项{{ .Imports }}。这是包的输出fmt

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go list <span style="color:var(--syntax-error-color)">-f</span> <span style="color:var(--syntax-string-color)">"{{ .Imports }}"</span> <span style="color:var(--syntax-text-color)">fmt</span>
<span style="color:var(--syntax-error-color)">[</span>errors internal/fmtsort io math os reflect strconv <span style="color:var(--syntax-text-color)">sync </span>unicode/utf8]
</code></span></span>

 

或者,您可以列出包的完整传递依赖集:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go list <span style="color:var(--syntax-error-color)">-f</span> <span style="color:var(--syntax-string-color)">"{{ .Deps  }}"</span> <span style="color:var(--syntax-text-color)">fmt</span>
<span style="color:var(--syntax-error-color)">[</span>errors internal/bytealg internal/cpu internal/fmtsort internal/oserror internal/poll internal/race internal/reflectlite internal/syscall/execenv internal/syscall/unix internal/testlog io math math/bits os reflect runtime runtime/internal/atomic runtime/internal/math runtime/internal/sys <span style="color:var(--syntax-text-color)">sort </span>strconv <span style="color:var(--syntax-text-color)">sync sync</span>/atomic syscall <span style="color:var(--syntax-text-color)">time </span>unicode unicode/utf8 unsafe]
</code></span></span>

 

您还可以使用go list命令检查依赖项和子依赖项的更新:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go list <span style="color:var(--syntax-error-color)">-m</span> <span style="color:var(--syntax-error-color)">-u</span> all
</code></span></span>

 

或者,检查特定依赖项的更新:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go list <span style="color:var(--syntax-error-color)">-m</span> <span style="color:var(--syntax-error-color)">-u</span> go.mongodb.org/mongo-driver
go.mongodb.org/mongo-driver v1.1.1 <span style="color:var(--syntax-error-color)">[</span>v1.4.0]
</code></span></span>

 

您可以使用该命令执行更多操作go list。确保检查文档以了解可能与该命令一起使用的标志和其他模板变量。

显示包或符号的文档

go doc命令打印与其参数标识的项目关联的文档注释
。它接受零个、一个或两个参数。

要显示当前目录中包的包文档,请使用不带任何参数的命令:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go doc
</code></span></span>

 

如果包是命令(main包),输出中将省略导出符号的文档,除非-cmd提供标志。

go doc通过将包的导入路径作为参数传递给命令,我们可以使用该命令查看任何包的文档:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go doc encoding/json
package json // import <span style="color:var(--syntax-string-color)">"encoding/json"</span>

Package json implements encoding and decoding of JSON as defined <span style="color:var(--syntax-declaration-color)">in </span>RFC 7159. The mapping between JSON and Go values is described <span style="color:var(--syntax-declaration-color)">in </span>the documentation <span style="color:var(--syntax-declaration-color)">for </span>the Marshal and Unmarshal functions.
<span style="color:var(--syntax-error-color)">[</span>truncated <span style="color:var(--syntax-declaration-color)">for </span>brevity]
</code></span></span>

 

如果您想查看包中特定方法的文档,只需将其作为第二个参数传递给go doc

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go doc encoding/json Marshal
</code></span></span>

 

第二个命令,godoc将所有 Go 包(包括您下载的任何第三方依赖项)的文档显示为网页。默认情况下,运行该命令将在端口 6060 上启动 Web 服务器,但您可以使用标志更改地址-http

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>godoc <span style="color:var(--syntax-error-color)">-http</span><span style="color:var(--syntax-error-color)">=</span>:6060
</code></span></span>

 

Chrome 中 fmt 的本地 Go 包文档

执行静态分析

go vet命令有助于检测代码中可能未被编译器捕获的可疑结构。这些可能不一定会阻止您的代码编译,但会影响代码质量,例如无法访问的代码、不必要的赋值和格式错误的字符串参数。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go vet main.go <span style="color:var(--syntax-comment-color)"># Run go vet on the `main.go` file</span>
<span style="color:var(--syntax-text-color)">$ </span>go vet <span style="color:var(--syntax-text-color)">.</span>       <span style="color:var(--syntax-comment-color)"># Run go vet on all the files in the current directory</span>
<span style="color:var(--syntax-text-color)">$ </span>go vet ./...   <span style="color:var(--syntax-comment-color)"># Run go vet recursively on all the files in the current directory</span>
</code></span></span>

 

此命令由几个分析器工具组成,在此处列出,每个分析器工具对
文件执行不同的检查。

go vet执行命令时默认执行所有检查。如果您只想执行特定检查(忽略所有其他检查),请将分析器的名称作为标志包含在内并将其设置为true. 这是一个单独运行检查的示例printf

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go vet <span style="color:var(--syntax-error-color)">-printf</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">true</span> ./...
</code></span></span>

 

但是,将-printf=false标志传递给go vet将运行除printf.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go vet <span style="color:var(--syntax-error-color)">-printf</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">false</span> ./...
</code></span></span>

 

将依赖项添加到您的项目

假设您启用了 Go 模块,go rungo build, 或go install将下载完成程序中导入语句所需的任何外部依赖项。默认情况下,如果没有可用的标记版本,将下载最新标记的版本或最新提交。

如果您需要下载特定版本的依赖项而不是 Go 默认获取的依赖项,您可以使用该go get命令。您可以针对特定版本或提交哈希:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go get github.com/joho/godotenv@v1.2.0
<span style="color:var(--syntax-text-color)">$ </span>go get github.com/joho/godotenv@d6ee687
</code></span></span>

 

此方法可用于根据需要升级或降级依赖项。任何下载的依赖项都存储在位于 的模块缓存中$GOPATH/pkg/mod。您可以使用go clean命令一次性清除所有项目的模块缓存:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go clean <span style="color:var(--syntax-error-color)">-modcache</span>
</code></span></span>

 

使用 Go 模块

我们在本系列的第 2 部分中详细介绍了 Go 模块。以下是有效使用模块所需了解的命令摘要:

  • go mod init将初始化项目中的模块。
  • go mod tidy清理未使用的依赖项或添加缺失的依赖项。确保在提交对代码的任何更改之前运行此命令。
  • go mod download会将所有模块下载到本地缓存。
  • go mod vendor将所有第三方依赖项复制到vendor项目根目录中的文件夹中。
  • go mod edit可用于将 go.mod 文件中的依赖项替换为本地或分叉版本。例如,如果您需要在上游合并补丁之前使用 fork,请使用以下代码:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>go mod edit <span style="color:var(--syntax-error-color)">-replace</span><span style="color:var(--syntax-error-color)">=</span>github.com/gizak/termui<span style="color:var(--syntax-error-color)">=</span>github.com/ayoisaiah/termui
</code></span></span>

 

测试和基准测试您的代码

Go 有一个内置的测试命令go test和一个testing包,它们可以结合起来提供简单但完整的单元测试体验。该test工具还包括基准测试和代码覆盖选项,可帮助您进一步分析代码。

让我们编写一个简单的测试来演示该工具的一些功能test。修改你文件中的代码main.go,如下图:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">package</span> <span style="color:var(--syntax-text-color)">main</span>

<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-string-color)">"fmt"</span>

<span style="color:var(--syntax-declaration-color)">func</span> <span style="color:var(--syntax-text-color)">welcome</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-declaration-color)">string</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-string-color)">"Welcome!"</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">func</span> <span style="color:var(--syntax-text-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">fmt</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">Println</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">welcome</span><span style="color:var(--syntax-text-color)">())</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

 

然后,将测试添加到main_test.go同一目录中的单独文件中:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">package</span> <span style="color:var(--syntax-text-color)">main</span>

<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-string-color)">"testing"</span>

<span style="color:var(--syntax-declaration-color)">func</span> <span style="color:var(--syntax-text-color)">TestWelcome</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">t</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">testing</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">T</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">expected</span> <span style="color:var(--syntax-error-color)">:=</span> <span style="color:var(--syntax-string-color)">"Welcome to Go!"</span>
    <span style="color:var(--syntax-text-color)">str</span> <span style="color:var(--syntax-error-color)">:=</span> <span style="color:var(--syntax-text-color)">welcome</span><span style="color:var(--syntax-text-color)">()</span>
    <span style="color:var(--syntax-declaration-color)">if</span> <span style="color:var(--syntax-text-color)">str</span> <span style="color:var(--syntax-error-color)">!=</span> <span style="color:var(--syntax-text-color)">expected</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-text-color)">t</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">Errorf</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"String was incorrect, got: %s, want: %s."</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">str</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">expected</span><span style="color:var(--syntax-text-color)">)</span>
    <span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

 

如果您go test在终端中运行,它应该会失败:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">test</span>
<span style="color:var(--syntax-error-color)">---</span> FAIL: TestSum <span style="color:var(--syntax-error-color)">(</span>0.00s<span style="color:var(--syntax-error-color)">)</span>
    main_test.go:9: String was incorrect, got: Welcome!, want: Welcome to Go!.
FAIL
<span style="color:var(--syntax-text-color)">exit </span>status 1
FAIL    github.com/ayoisaiah/demo   0.002s
</code></span></span>

 

welcome我们可以通过修改文件中函数的返回值来使测试通过main.go

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">func</span> <span style="color:var(--syntax-text-color)">welcome</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-declaration-color)">string</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-string-color)">"Welcome to Go!"</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

 

现在,测试应该成功通过:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">test
</span>PASS
ok      github.com/ayoisaiah/demo   0.002s
</code></span></span>

 

如果您有很多带有测试功能的测试文件,但只想有选择地运行其中的几个,则可以使用该-run标志。它接受一个正则表达式字符串来匹配您要运行的测试函数:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">test</span> <span style="color:var(--syntax-error-color)">-run</span><span style="color:var(--syntax-error-color)">=</span>^TestWelcome<span style="color:var(--syntax-text-color)">$ </span><span style="color:var(--syntax-text-color)">.</span> <span style="color:var(--syntax-comment-color)"># Run top-level tests matching "TestWelcome"</span>
<span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">test</span> <span style="color:var(--syntax-error-color)">-run</span><span style="color:var(--syntax-error-color)">=</span> String <span style="color:var(--syntax-text-color)">.</span>       <span style="color:var(--syntax-comment-color)"># Run top-level tests matching "String" such as "TestStringConcatenation"</span>
</code></span></span>

 

你还应该知道以下测试标志,在测试 Go 程序时它们经常派上用场

  • -v标志启用详细模式,以便在输出中打印测试的名称。
  • -short标志跳过长时间运行的测试。
  • -failfast标志在第一次失败的测试后停止测试。
  • -count标志连续多次运行测试,如果您想检查间歇性故障,这将很有用。

代码覆盖率

要查看您的代码覆盖率状态,请使用-cover标志,如下所示:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">test</span> <span style="color:var(--syntax-error-color)">-cover</span>
PASS
coverage: 50.0% of statements
ok      github.com/ayoisaiah/demo   0.002s
</code></span></span>

 

您还可以使用标志生成覆盖率配置文件-coverprofile。这使您可以更详细地研究代码覆盖率结果:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">test</span> <span style="color:var(--syntax-error-color)">-coverprofile</span><span style="color:var(--syntax-error-color)">=</span>coverage.out
</code></span></span>

 

coverage.out运行上述命令后,您将在当前目录中找到一个文件。此文件中包含的信息可用于输出一个 HTML 文件,其中包含已被现有测试覆盖的确切代码行。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go tool cover <span style="color:var(--syntax-error-color)">-html</span><span style="color:var(--syntax-error-color)">=</span>coverage.out
</code></span></span>

 

运行此命令时,会弹出一个浏览器窗口,以绿色显示覆盖线,以红色显示未覆盖线。

Chrome 中的代码覆盖率信息截图

对标

Go 中的基准测试工具被广泛接受为衡量 Go 代码性能的可靠方法。基准测试放置在_test.go文件中,就像测试一样。下面是一个比较 Go 中不同字符串连接方法性能的示例:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-comment-color)">// main_test.go</span>
<span style="color:var(--syntax-declaration-color)">package</span> <span style="color:var(--syntax-text-color)">main</span>

<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">(</span>
    <span style="color:var(--syntax-string-color)">"bytes"</span>
    <span style="color:var(--syntax-string-color)">"strings"</span>
    <span style="color:var(--syntax-string-color)">"testing"</span>
<span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-declaration-color)">var</span> <span style="color:var(--syntax-text-color)">s1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-string-color)">"random"</span>

<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-text-color)">LIMIT</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-literal-color)">1000</span>

<span style="color:var(--syntax-declaration-color)">func</span> <span style="color:var(--syntax-text-color)">BenchmarkConcatenationOperator</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">b</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">testing</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">B</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">var</span> <span style="color:var(--syntax-text-color)">q</span> <span style="color:var(--syntax-declaration-color)">string</span>
    <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">i</span> <span style="color:var(--syntax-error-color)">:=</span> <span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">i</span> <span style="color:var(--syntax-error-color)"><</span> <span style="color:var(--syntax-text-color)">b</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">N</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">i</span><span style="color:var(--syntax-error-color)">++</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">j</span> <span style="color:var(--syntax-error-color)">:=</span> <span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">j</span> <span style="color:var(--syntax-error-color)"><</span> <span style="color:var(--syntax-text-color)">LIMIT</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">j</span><span style="color:var(--syntax-error-color)">++</span> <span style="color:var(--syntax-text-color)">{</span>
            <span style="color:var(--syntax-text-color)">q</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">q</span> <span style="color:var(--syntax-error-color)">+</span> <span style="color:var(--syntax-text-color)">s1</span>
        <span style="color:var(--syntax-text-color)">}</span>
        <span style="color:var(--syntax-text-color)">q</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-string-color)">""</span>
    <span style="color:var(--syntax-text-color)">}</span>
    <span style="color:var(--syntax-text-color)">b</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">ReportAllocs</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">func</span> <span style="color:var(--syntax-text-color)">BenchmarkStringBuilder</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">b</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">testing</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">B</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">var</span> <span style="color:var(--syntax-text-color)">q</span> <span style="color:var(--syntax-text-color)">strings</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">Builder</span>
    <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">i</span> <span style="color:var(--syntax-error-color)">:=</span> <span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">i</span> <span style="color:var(--syntax-error-color)"><</span> <span style="color:var(--syntax-text-color)">b</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">N</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">i</span><span style="color:var(--syntax-error-color)">++</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">j</span> <span style="color:var(--syntax-error-color)">:=</span> <span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">j</span> <span style="color:var(--syntax-error-color)"><</span> <span style="color:var(--syntax-text-color)">LIMIT</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">j</span><span style="color:var(--syntax-error-color)">++</span> <span style="color:var(--syntax-text-color)">{</span>
            <span style="color:var(--syntax-text-color)">q</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">WriteString</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">s1</span><span style="color:var(--syntax-text-color)">)</span>
        <span style="color:var(--syntax-text-color)">}</span>
        <span style="color:var(--syntax-text-color)">q</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">Reset</span><span style="color:var(--syntax-text-color)">()</span>
    <span style="color:var(--syntax-text-color)">}</span>
    <span style="color:var(--syntax-text-color)">b</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">ReportAllocs</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">func</span> <span style="color:var(--syntax-text-color)">BenchmarkBytesBuffer</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">b</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">testing</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">B</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">var</span> <span style="color:var(--syntax-text-color)">q</span> <span style="color:var(--syntax-text-color)">bytes</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">Buffer</span>
    <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">i</span> <span style="color:var(--syntax-error-color)">:=</span> <span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">i</span> <span style="color:var(--syntax-error-color)"><</span> <span style="color:var(--syntax-text-color)">b</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">N</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">i</span><span style="color:var(--syntax-error-color)">++</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">j</span> <span style="color:var(--syntax-error-color)">:=</span> <span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">j</span> <span style="color:var(--syntax-error-color)"><</span> <span style="color:var(--syntax-text-color)">LIMIT</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">j</span><span style="color:var(--syntax-error-color)">++</span> <span style="color:var(--syntax-text-color)">{</span>
            <span style="color:var(--syntax-text-color)">q</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">WriteString</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">s1</span><span style="color:var(--syntax-text-color)">)</span>
        <span style="color:var(--syntax-text-color)">}</span>
        <span style="color:var(--syntax-text-color)">q</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">Reset</span><span style="color:var(--syntax-text-color)">()</span>
    <span style="color:var(--syntax-text-color)">}</span>
    <span style="color:var(--syntax-text-color)">b</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">ReportAllocs</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">func</span> <span style="color:var(--syntax-text-color)">BenchmarkByteSlice</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">b</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">testing</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">B</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">var</span> <span style="color:var(--syntax-text-color)">q</span> <span style="color:var(--syntax-text-color)">[]</span><span style="color:var(--syntax-declaration-color)">byte</span>
    <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">i</span> <span style="color:var(--syntax-error-color)">:=</span> <span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">i</span> <span style="color:var(--syntax-error-color)"><</span> <span style="color:var(--syntax-text-color)">b</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">N</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">i</span><span style="color:var(--syntax-error-color)">++</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">j</span> <span style="color:var(--syntax-error-color)">:=</span> <span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">j</span> <span style="color:var(--syntax-error-color)"><</span> <span style="color:var(--syntax-text-color)">LIMIT</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">j</span><span style="color:var(--syntax-error-color)">++</span> <span style="color:var(--syntax-text-color)">{</span>
            <span style="color:var(--syntax-text-color)">q</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">append</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">q</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">s1</span><span style="color:var(--syntax-error-color)">...</span><span style="color:var(--syntax-text-color)">)</span>
        <span style="color:var(--syntax-text-color)">}</span>
        <span style="color:var(--syntax-text-color)">q</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-declaration-color)">nil</span>
    <span style="color:var(--syntax-text-color)">}</span>
    <span style="color:var(--syntax-text-color)">b</span><span style="color:var(--syntax-error-color)">.</span><span style="color:var(--syntax-text-color)">ReportAllocs</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

 

可以使用以下go test -bench=.命令调用此基准测试:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">test</span> <span style="color:var(--syntax-error-color)">-bench</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">.</span>
goos: linux
goarch: amd64
pkg: github.com/ayoisaiah/demo
BenchmarkConcatenationOperator-4        1718        655509 ns/op     3212609 B/op        999 allocs/op
BenchmarkStringBuilder-4              105122         11625 ns/op       21240 B/op         13 allocs/op
BenchmarkBytesBuffer-4                121896          9230 ns/op           0 B/op          0 allocs/op
BenchmarkByteSlice-4                  131947          9903 ns/op       21240 B/op         13 allocs/op
PASS
ok      github.com/ayoisaiah/demo   5.166s
</code></span></span>

 

如您所见,连接运算符是其中最慢的,每次操作耗时 655509 纳秒,而bytes.Buffer最快的是每次操作耗时 9230 纳秒。以这种方式编写基准测试是以可重现的方式确定性能改进或回归的最佳方式。

检测竞争条件

该工具包含一个竞争检测器go,可以通过选件激活-race。这对于查找并发系统中可能导致崩溃和内存损坏的问题很有用。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">test</span> <span style="color:var(--syntax-error-color)">-race</span> ./...
<span style="color:var(--syntax-text-color)">$ </span>go run <span style="color:var(--syntax-error-color)">-race</span> main.go
<span style="color:var(--syntax-text-color)">$ </span>go build <span style="color:var(--syntax-error-color)">-race</span> ./...
<span style="color:var(--syntax-text-color)">$ </span>go <span style="color:var(--syntax-text-color)">install</span> <span style="color:var(--syntax-error-color)">-race</span> ./...
</code></span></span>

 

总结

在本文中,我们介绍了每个 Go 环境中包含的几个工具,并提供了
如何使用它们的简短描述。

如果您喜欢这篇文章,请点赞、评论和分享。

...全文
259 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

1,071

社区成员

发帖
与我相关
我的任务
社区描述
Go+ 官方开发者社区。我们希望向广大的开发者和数据科学家介绍 Go+ 的定位和意义,并邀请更多开发者一起贡献代码、共建 Go+ 生态。 Go+ 官网:https://goplus.org/
其他 企业社区
社区管理员
  • Go+
  • 杨东杰
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

本社区为 Go+ 官方开发者社区。我们希望向广大的开发者和数据科学家介绍 Go+ 的定位和意义,并邀请更多开发者一起贡献代码、共建 Go+ 生态。

Go+ 官网:https://goplus.org/
GitHub地址:https://github.com/goplus/gop

试试用AI创作助手写篇文章吧