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 下找到。