go包悬停文档只能由gopls解析源码注释生成,不依赖用户配置;改settings.json或插件设置无效,因gopls自0.13起弃用外部工具,仅认紧贴声明的规范注释(如/.../或连续//),且需满足无空行、大小写一致等硬性条件。

Go 包的悬停文档不能靠用户侧配置“自定义”,只能通过包自身的 docstring 或 go:generate 工具链注入,且最终展示效果取决于 gopls 是否能解析到这些内容。
为什么改 settings.json 或插件设置没用
VSCode 的 Go 悬停提示完全由语言服务器 gopls 提供,不是前端 UI 层可配置的功能。你改 "go.docsTool"、关/开 "useLanguageServer"、甚至换 gogetdoc 都已失效——gopls 自 0.13 起已弃用所有外部文档工具,只认源码注释和内置符号表。
-
gopls不读取本地godoc服务或go doc命令输出 - 插件设置里所谓 “Hover delay”、“Markdown preview” 等只影响渲染时机和样式,不改变内容来源
- 第三方扩展(如 “Go Doc”)在
gopls启用后基本被忽略,注册的HoverProvider会被优先级更高的gopls覆盖
真正有效的自定义方式:写符合 gopls 规范的包注释
gopls 解析的是 Go 源码顶部的 package 注释块,且必须满足两个硬性条件:
- 注释必须紧贴
package xxx声明前,中间不能有空行 - 必须是
/* ... */或//风格,但//只支持单行(多行需用/* */)
例如有效写法:
/*
Package myutil 提供常用工具函数。
<p>本包依赖 net/http 和 encoding/json,不建议在性能敏感路径中直接调用 HTTPClient.Do。</p><p>示例:
result, err := myutil.FetchJSON("<a href="https://www.php.cn/link/46b315dd44d174daf5617e22b3ac94ca">https://www.php.cn/link/46b315dd44d174daf5617e22b3ac94ca</a>")
*/
package myutil
</p>
无效写法(悬停会显示 “No documentation for package myutil”):
- 注释和
package之间有空行 - 用了
/** */(Go 不识别 JSDoc 风格) - 注释写在
package行之后 - 包名大小写与
go mod init声明不一致(比如模块是github.com/user/myutil,但包声明为package myUtil)
函数/类型级文档怎么加才生效
函数、方法、结构体的悬停内容来自其上方紧邻的注释块,规则比包注释更严格:
- 必须用
/* */或连续的//(每行以//开头,无空行中断) - 注释第一行不能是空行,也不能是纯分隔线(如
// ---) - 不要混用
@param这类 JSDoc 标签——gopls不解析它们,只当普通文本渲染
正确示例:
// FetchJSON 发起 GET 请求并解析 JSON 响应。
// 如果 status code 非 2xx,返回 *url.Error。
// 注意:超时默认为 30s,可通过 context.WithTimeout 控制。
func FetchJSON(url string) (map[string]interface{}, error) {
// ...
}
错误示例:
-
/* @func FetchJSON */——@func被忽略,但注释本身仍显示;加了反而干扰阅读 - 注释里嵌入 Markdown 表格或代码块(
```go)——gopls返回的是纯文本片段,VSCode 悬停层不渲染多行代码块 - 在函数签名和注释之间插入空行——
gopls认为注释不属于该函数
调试悬停不显示的三个必查点
即使注释全对,悬停仍为空,大概率卡在这三处:
-
gopls还没加载完:右下角状态栏看是否显示gopls (initializing...);新开一个 .go 文件等几秒再试 - 文件没被
go mod管理:没有go.mod文件时,gopls降级为语法模式,不解析跨包引用和完整文档 - 光标位置不对:悬停必须放在标识符“正上方”,比如
FetchJSON的F上;放在括号内、逗号后、或 import 路径里都无效
验证是否真解析成功:打开命令面板(Ctrl+Shift+P),运行 Developer: Toggle Developer Tools,在 Console 里输入 await gopls.getDocumentation({uri: vscode.window.activeTextEditor?.document.uri.toString(), position: {line: X, character: Y}})(X/Y 替换为当前光标行列),看返回是否有 contents 字段。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











