Gopls v0.16.0 发布
go install golang.org/x/tools/gopls@v0.16.2
此版本包含多项新功能和错误修复,并且是 gopls 首个支持 Go 1.23 的版本。要安装它,请运行
新的支持策略;不再支持 Go 1.19 和 Go 1.20
简而言之:我们正在缩小 gopls 的支持窗口,但只要您使用至少 Go 1.21 来构建 gopls,这对您几乎没有影响。这不会影响 gopls 对您正在编写的代码的支持。
这是 gopls 支持 Go 1.19 或 Go 1.20 构建的最后一个版本,也是最后一个支持与 go 命令版本 1.19 和 1.20 集成的版本。如果使用这两个 Go 版本之一构建或使用,它将显示一条消息建议用户升级。
在使用 gopls 时,有三个版本需要注意
- gopls 构建所使用的 Go 版本:用于构建 gopls 的 Go 版本。
- go 命令版本:gopls 执行的 go list 命令的版本,用于加载工作区信息。
- 语言版本:当前文件所属 go.mod 文件中 go 指令的版本,它决定了该文件的 Go 语言语义。
此 gopls 版本 v0.16.0,是最后一个支持 Go 1.19 和 Go 1.20 作为gopls 构建所使用的 Go 版本或go 命令版本的版本。gopls 对所有语言版本的支持没有变化——事实上,通过添加 stdversion
分析器(见下文),支持有所改进。
从 gopls@v0.17.0 开始,该版本将在 Go 1.23.0 于 8 月发布后发布,gopls 将仅支持最新版本的 Go 作为gopls 构建所使用的 Go 版本。然而,得益于 Go 1.21 中添加的向前兼容性,任何必要的工具链升级都应该像其他依赖项一样自动为 Go 1.21 或更高版本的用户处理。此外,我们将go 命令版本的支持窗口从 4 个版本缩减到 3 个。请注意,这意味着如果您至少在系统上安装了 Go 1.21,您仍然可以 go install
并使用 gopls@v0.17.0。
我们无意改变语言版本支持:我们预计 gopls 将始终支持开发针对任何 Go 版本的程序。
通过专注于使用最新 Go 版本构建 gopls,我们可以显著减轻维护负担,并有助于提高未来 gopls 版本稳定性的。有关详情,请参阅新更新的支持策略。如果您对此次更改有任何疑虑,请在 golang/go#65917 上发表评论。
配置更改
- 实验性的
allowImplicitNetworkAccess
设置已被弃用(但尚未移除)。如果您使用此设置并且将受到其移除的影响,请在 golang/go#66861 上发表评论。
新功能
Go 1.23 支持
此 gopls 版本首次支持 Go 1.23 的新语言特性,包括基于函数的 range 迭代器以及对 go.mod 文件中godebug
指令的支持。
集成文档查看器
Gopls 现在提供一个“浏览文档”代码操作,该操作会打开一个本地网页,以类似于 https://pkg.go.dev 的格式显示 Go 包和符号的生成文档。包或符号是根据当前选中的内容选择的。
使用此功能可以在准备 API 更改时预览标记的文档,或阅读本地编辑的包的文档,即使是尚未保存的包。编辑后请刷新页面以查看更新的文档。

与 pkg.go.dev
一样,每个符号的标题都包含一个指向其声明源代码的链接。在 pkg.go.dev
中,这些链接会指向 GitHub 或 Google Code Search 等网站的源代码页面。但是,在 gopls 的内部查看器中,单击这些链接中的一个将导致您的编辑器导航到声明。(此功能要求您的 LSP 客户端能够响应 showDocument
下行调用。)

编辑器支持
- VS Code:使用“Source action > Browse documentation for func fmt.Println”菜单项。注意:源链接可以导航编辑器,但尚未能弹出窗口。请为 microsoft/vscode#208093 和 microsoft/vscode#207634(已暂时关闭)投票。
- Emacs:需要 eglot v1.17。从 github.com/dominikh/go-mode.el 使用
M-x go-browse-doc
。
linksInHover
设置现在支持一个新的值 "gopls"
,它会导致 Hover 操作的 Markdown 输出中的文档链接指向 gopls 的内部文档查看器。
浏览自由符号
Gopls 提供另一个基于 Web 的代码操作“Browse free symbols”(浏览自由符号),它显示所选代码引用的自由符号。
如果一个符号在选区内被引用但在选区外声明,则该符号是“自由”的。自由符号变量集大致等于将该块提取到自己的函数中所需的参数集。
即使您不打算将一个代码块提取到新函数中,这些信息也能帮助您一目了然地了解一段代码依赖于哪些名称。
每个标识符的点状路径(例如 file.Name.Pos
)都会被报告为一个单独的项目,以便您可以看到复杂类型中实际需要哪些部分。
函数体的自由符号可能会显示,函数的一个参数(例如,结构体的单个字段)只被使用了很小的部分,这使得您可以通过选择该参数的不同类型来简化和泛化函数。

编辑器支持
- VS Code:使用
Source action > Browse free symbols
菜单项。 - Emacs:需要 eglot v1.17。从 github.com/dominikh/go-mode.el 使用
M-x go-browse-freesymbols
。
浏览汇编
Gopls 提供第三个基于 Web 的代码操作“Browse assembly for f”(为函数 f 浏览汇编),它显示了包含所选代码的函数 f 的声明的汇编列表,以及任何嵌套函数,如函数字面量或延迟调用。
Gopls 调用编译器来生成报告;刷新页面会更新报告。
机器架构由 gopls 为当前文件选择的构建配置确定。这通常与您的机器的 GOARCH 相同,除非您正在处理带有针对不同架构的 go:build
标签的文件。

Gopls 尚不能显示泛型函数的汇编:泛型函数在实例化之前不会被完全编译,但包含所选内容的任何函数声明都不可能是实例化的泛型函数。
编辑器支持
- VS Code:使用“Source action > Browse assembly for f”菜单项。
- Emacs:需要 eglot v1.17。从 github.com/dominikh/go-mode.el 使用
M-x go-browse-assembly
。
unusedwrite
分析器
新的unusedwrite 分析器报告赋值,通常是结构体字段的赋值,这些赋值无效,例如,因为结构体再也没有被使用。
func scheme(host string) string {
u := &url.URL{
Host: host, // "unused write to field Host" (no need to construct a URL)
Scheme: "https:",
}
return u.Scheme
}
这最多表明代码不必要地复杂(例如,可以删除一些死代码),但通常表示一个错误,如下例所示
type S struct { x int }
func (s S) set(x int) {
s.x = x // "unused write to field x" (s should be a *S pointer)
}
stdversion
分析器
新的stdversion
分析器会根据您的 go.mod
文件中的 go
指令版本,警告使用过于新的标准库符号。这改进了我们对旧语言版本(见上文)的支持,即使 gopls 使用最新的 Go 版本构建。
考虑下面的 go.mod 文件和 Go 文件。var
alias 的声明引用了一个类型 types.Alias
,它在 go1.22 中引入,但该文件属于一个只要求 go1.21 的模块,因此分析器会报告一个诊断。
module example.com
go 1.21
package p
import "go/types"
var alias types.Alias // types.Alias requires go1.22 or later (module is go1.21)
当单个文件被 build-tagged 为模块版本之外的 Go 版本时,分析器将应用适合该文件版本的检查。
另外两个 vet 分析器
framepointer
和 sigchanyzer
分析器一直是 go vet 套件的一部分,但在之前的 gopls 版本中被忽略了。
从现在开始,gopls 将始终包含 vet 运行的任何分析器。
Hover 显示大小/偏移量信息,以及结构体标签
将鼠标悬停在声明类型或结构体字段的标识符上,现在会显示类型的尺寸信息

以及字段的偏移量信息

此外,它还会报告由于结构体字段顺序不佳而浪费的空间百分比,如果这个数字是 20% 或更高

在上面的结构体中,对齐规则要求两个布尔字段(1 字节)中的每一个都占用一个完整的字(8 字节),导致浪费了 (7 + 7) / (3 * 8) = 58% 的空间。将两个布尔值放在一起可以节省一个字。
这些信息在对数据结构进行空间优化时,或在阅读汇编代码时可能很有帮助。
另外,将鼠标悬停在带有结构体标签的字段引用上,现在也会显示该标签

Hover 和“转到定义”在文档注释中的符号上起作用
Go 1.19 添加了对文档链接的支持,允许一个符号的文档注释引用另一个符号。
Gopls 的 Hover 和 Definition 操作现在将这些链接视为标识符,因此将鼠标悬停在其中一个上会显示该符号的信息

类似地,“转到定义”将导航到其声明。感谢 @rogeryk 为此功能做出的贡献。
已修复的 Bug
感谢我们的贡献者!
@guodongli-google 贡献了 unusedwrite
分析器。待定:他是一位前 Google 员工;是否有更近期的 GH 账号?
@rogeryk
本文档的源代码可以在 golang.org/x/tools/gopls/doc 下找到。