Gopls release v0.19.0

配置更改

  • gopls check 子命令现在接受一个 -severity 标志,用于设置它报告的诊断的最低严重级别。默认情况下,最低严重级别是“warning”,因此 gopls check 可能会报告比以前少的诊断。设置 -severity=hint 以重现以前的行为。

“实现”支持签名类型(同一包内)

实现查询根据方法集报告抽象类型和具体类型及其方法之间的对应关系。现在,它还根据签名报告函数类型、动态函数调用和函数定义之间的对应关系。

要使用它,请在命名函数、命名方法或函数字面量的定义的 func 标记上调用实现查询。Gopls 将报告抽象该函数的函数签名类型集,以及通过此类类型的值进行的动态调用集。

反之,在签名类型的 func 标记上,或在动态函数调用的 ( 括号上调用实现查询,将报告该签名所抽象的,或该调用分派到的具体函数集。

由于一个类型可能既是函数类型又是带方法的命名类型(例如,http.HandlerFunc),因此它可能参与两种类型的实现查询(方法集和函数签名)。使用方法集进行的查询应在类型或方法名称上调用,使用签名进行的查询应在 func( 标记上调用。

目前仅支持本地(同一包内)算法。(https://golang.ac.cn/issue/56572 跟踪全局算法。)

“转到实现”报告接口到接口的关系

“转到实现”操作现在报告接口之间的关系。Gopls 现在使用查询类型的具体性来确定查询是“向下”(从接口到实现它的类型)还是“向上”(从具体类型到它可以分配到的接口)。例如:

  • implementation(io.Reader) 子接口,例如 io.ReadCloser,以及具体实现,例如 *os.File

  • implementation(os.File) 仅包含接口,例如 io.Readerio.ReadCloser

要从接口开始请求“向上”查询,例如查找 io.ReadCloser 的超接口,请使用下面描述的类型层级结构功能。(请参阅 https://github.com/microsoft/language-server-protocol/issues/2037。)

支持类型层级结构

Gopls 现在实现了与类型层级结构查看器相关的三个 LSP 方法:textDocument/prepareTypeHierarchytypeHierarchy/supertypestypeHierarchy/subtypes

在 VS Code 中,从上下文菜单中选择“Show Type Hierarchy”(显示类型层级结构)以查看显示所选命名类型的所有超类型或子类型的树状控件。

编辑功能

补全:为新 Go 文件自动补全 package 子句

Gopls 现在会自动为新创建的 Go 文件添加适当的 package 子句,以便您可以立即开始编写有趣的部分。

它需要客户端支持 workspace/didCreateFiles

新的 GOMODCACHE 索引,用于更快的 Organize Imports 和未导入的补全

默认情况下,gopls 现在构建并维护模块缓存(GOMODCACHE)中包的持久索引。Organize Imports 和来自未导入包的符号补全的操作速度提高了十倍。

要恢复到旧行为,请将 importsSource 选项(新默认值为 "gopls")设置为 "goimports"。不希望将模块缓存用于 imports 或 completions 的用户可以将该选项更改为“off”。

分析功能

大多数 staticcheck 分析器默认启用

Staticcheck 套件中的分析器数量略多于一半现在默认启用。此子集已选择用于精确性和效率。

以前,仅当启用了实验性的 staticcheck 布尔选项时,才会运行 Staticcheck 分析器(全部)。此值继续启用完整集,而 false 值继续禁用完整集。将该选项留空会启用首选的分析器子集。

Staticcheck 分析器与其他所有分析器一样,可以使用 analyzers 配置设置显式启用或禁用;此设置现在优先于 staticcheck 设置,因此,无论您使用 staticcheck 的哪个值(true/false/unset),您都可以根据首选的分析器集进行调整。

recursiveiter:“低效的递归迭代器”

编写一个为递归数据类型返回迭代器(iter.Seq)的函数时,一个常见的陷阱是从其自身实现中递归调用该函数,这会导致嵌套协程的堆栈,效率低下。

新的 recursiveiter 分析器会检测此类错误;有关详细信息,请参阅其文档,包括有关如何定义简单高效的递归迭代器的提示。

maprange:“低效的 map.Keys/Values 范围循环”

新的 maprange 分析器会检测在 range 循环的操作数处对 maps.Keysmaps.Values 的冗余调用;当然,map 可以直接进行 range 循环。有关详细信息,请参阅其文档)。

代码转换功能

重命名方法接收器

当重命名操作应用于方法接收器的声明时,现在也会尝试重命名与同一命名类型相关的所有其他方法的接收器。无法完全重命名的其他接收器将被静默跳过。

重命名方法接收器的使用继续仅影响该变量。

type Counter struct { x int }

                 Rename here to affect only this method
                          ↓
func (c *Counter) Inc() { c.x++ }
func (c *Counter) Dec() { c.x++ }
      ↑
  Rename here to affect all methods

“消除点导入”代码操作

此代码操作可在点导入上使用,它将提供用常规导入替换该导入,并使用包名限定每个使用。

为结构体字段添加/删除标签

Gopls 现在提供两个新的代码操作,可在整个结构体或其部分字段上使用,允许您添加和删除结构体标签。它仅添加具有 snakecase 命名格式的“json”标签,或清除所选范围内的所有标签。

添加标签示例

type Info struct {
    LinkTarget string        ->      LinkTarget string `json:"link_target"`
    ...
}

内联局部变量

新的 refactor.inline.variable 代码操作会用变量的初始化表达式替换对局部变量的引用。例如,当应用于 println(s) 中的 s 时:

func f(x int) {
    s := fmt.Sprintf("+%d", x)
    println(s)
}

它将代码转换为:

func f(x int) {
    s := fmt.Sprintf("+%d", x)
    println(fmt.Sprintf("+%d", x))
}

仅替换一个引用;https://golang.ac.cn/issue/70085 跟踪“内联所有”变量用法并消除它的功能。

感谢我们的贡献者!

@acehinnnqru @adonovan @albfan @aarzilli @ashurbekovz @cuonglm @dmitshur @neild @egonelbre @shashank priyadarshi @firelizzard18 @gopherbot @h9jiang @cuishuang @jakebailey @jba @madelinekalil @karamaru alpha @danztran @nsrip dd @pjweinb @findleyr @samthanawalla @seankhliao @tklauser @vikblom @kwjw @xieyuschen


本文档的源代码可以在 golang.org/x/tools/gopls/doc 下找到。