Go 部落格
熟悉工作區
Go 1.18 增加了工作區模式,讓您可以同時處理多個模組。
您可以透過訪問 下載 頁面來獲取 Go 1.18。 發行說明 包含所有更改的更多詳細資訊。
工作區
Go 1.18 中的 工作區 允許您同時處理多個模組,而無需編輯每個模組的 go.mod
檔案。工作區內的每個模組在解析依賴項時都會被視為主模組。
以前,要在其中一個模組中新增一個功能並在另一個模組中使用它,您需要釋出第一個模組的更改,或者使用 replace
指令 編輯 go.mod 檔案以引用您本地的、未釋出的模組更改。為了無誤地釋出,您必須在將本地更改釋出到第一個模組後,從依賴模組的 go.mod
檔案中刪除 replace
指令。
使用 Go 工作區,您可以透過工作區目錄根目錄中的 go.work
檔案來控制所有依賴項。go.work
檔案包含 use
和 replace
指令,它們會覆蓋單個 go.mod
檔案,因此無需單獨編輯每個 go.mod
檔案。
要建立工作區,請在工作區目錄列表上執行 go work init
,並將模組目錄作為空格分隔的引數。工作區不需要包含您正在處理的模組。init
命令會建立一個 go.work
檔案,其中列出了工作區中的模組。如果您在沒有引數的情況下執行 go work init
,該命令將建立一個空工作區。
要將模組新增到工作區,請執行 go work use [moddir]
或手動編輯 go.work
檔案。執行 go work use -r .
可以遞迴地將引數目錄中帶有 go.mod
檔案的目錄新增到您的工作區。如果一個目錄沒有 go.mod
檔案,或者不再存在,則該目錄的 use
指令將從您的 go.work
檔案中移除。
go.work
檔案的語法與 go.mod
檔案類似,幷包含以下指令:
go
:go 工具鏈版本,例如go 1.18
use
:將磁碟上的模組新增到工作區中的主模組集。其引數是包含模組go.mod
檔案的目錄的相對路徑。use
指令不會新增指定目錄子目錄中的模組。replace
:與go.mod
檔案中的replace
指令類似,go.work
檔案中的replace
指令會將模組的 *特定版本* 或 *所有版本* 的內容替換為在其他地方找到的內容。
工作流
工作區非常靈活,支援各種工作流。以下部分將簡要概述我們認為最常見的工作流。
向外部模組新增功能並在您自己的模組中使用
-
為您的工作區建立一個目錄。
-
克隆您要編輯的外部模組。
-
在外部模組的本地版本中新增您的功能。
-
在工作區資料夾中執行
go work init [path-to-upstream-mod-dir]
。 -
修改您自己的模組,以實現新增到外部模組中的功能。
-
在工作區資料夾中執行
go work use [path-to-your-module]
。go work use
命令將您的模組路徑新增到您的go.work
檔案中。go 1.18 use ( ./path-to-upstream-mod-dir ./path-to-your-module )
-
執行並測試您模組中使用新新增的外部模組功能。
-
釋出帶有新功能的外部模組。
-
釋出使用新功能的您的模組。
在同一儲存庫中處理多個相互依賴的模組
在同一儲存庫中處理多個模組時,go.work
檔案定義了工作區,而不是使用每個模組 go.mod
檔案中的 replace
指令。
-
為您的工作區建立一個目錄。
-
克隆包含您要編輯的模組的儲存庫。這些模組不必放在您的工作區資料夾中,因為您可以使用
use
指令指定每個模組的相對路徑。 -
在您的工作區目錄中執行
go work init [path-to-module-one] [path-to-module-two]
。示例:您正在處理
example.com/x/tools/groundhog
,它依賴於example.com/x/tools
模組中的其他包。克隆儲存庫,然後在您的工作區資料夾中執行
go work init tools tools/groundhog
。您的
go.work
檔案的內容如下所示:go 1.18 use ( ./tools ./tools/groundhog )
在
tools
模組中進行的任何本地更改都將由您工作區中的tools/groundhog
使用。
在依賴項配置之間切換
要在不同的依賴項配置下測試您的模組,您可以建立多個具有單獨 go.work
檔案的工作區,或者保留一個工作區並在單個 go.work
檔案中註釋掉您不想要的 use
指令。
建立多個工作區
- 為不同的依賴項需求建立單獨的目錄。
- 在每個工作區目錄中執行
go work init
。 - 透過
go work use [path-to-dependency]
在每個目錄中新增您想要的依賴項。 - 在每個工作區目錄中執行
go run [path-to-your-module]
,以使用其go.work
檔案指定的依賴項。
要在同一工作區中測試不同的依賴項,請開啟 go.work
檔案並新增或註釋掉所需的依賴項。
仍在 Gopath 下工作?
也許使用工作區會改變您的想法。GOPATH
使用者可以使用位於其 GOPATH
目錄根目錄下的 go.work
檔案來解析其依賴項。工作區並非旨在完全重現所有 GOPATH
工作流,但它們可以建立一個共享 GOPATH
部分便利性,同時仍提供模組優勢的設定。
為 GOPATH 建立工作區
- 在您的
GOPATH
目錄的根目錄下執行go work init
。 - 要在您的工作區中使用本地模組或特定版本作為依賴項,請執行
go work use [path-to-module]
。 - 要替換您模組
go.mod
檔案中的現有依賴項,請使用go work replace [path-to-module]
。 - 要新增 GOPATH 或任何目錄中的所有模組,請執行
go work use -r
以遞迴地將帶有go.mod
檔案的目錄新增到您的工作區。如果一個目錄沒有go.mod
檔案,或者不再存在,則該目錄的use
指令將從您的go.work
檔案中移除。
注意:如果您有不帶
go.mod
檔案但您想新增到工作區的專案,請進入其專案目錄並執行go mod init
,然後使用go work use [path-to-module]
將新模組新增到您的工作區。
工作區命令
除了 go work init
和 go work use
,Go 1.18 還為工作區引入了以下命令:
go work sync
:將go.work
檔案中的依賴項推回到每個工作區模組的go.mod
檔案中。go work edit
:提供一個命令列介面來編輯go.work
,主要供工具或指令碼使用。
模組感知構建命令和一些 go mod
子命令會檢查 GOWORK
環境變數,以確定它們是否處於工作區上下文中。
如果 GOWORK
變數指向一個以 .work
結尾的檔案路徑,則啟用工作區模式。要確定正在使用哪個 go.work
檔案,請執行 go env GOWORK
。如果 go
命令不在工作區模式下,輸出將為空。
啟用工作區模式後,將解析 go.work
檔案,以確定工作區模式的三個引數:Go 版本、目錄列表和替換列表。
一些可以在工作區模式下嘗試的命令(前提是您已經知道它們的作用!)
go work init
go work sync
go work use
go list
go build
go test
go run
go vet
編輯器體驗改進
我們特別高興 Go 的語言伺服器 gopls 和 VSCode Go 擴充套件 的升級,它們使得在 LSP 相容編輯器中處理多個模組的體驗流暢且富有成效。
在工作區內的模組之間,查詢引用、程式碼補全和跳轉到定義都可以正常工作。gopls
版本 0.8.1 引入了對 go.work
檔案的診斷、補全、格式化和懸停功能。您可以利用這些 gopls 功能與任何 LSP 相容編輯器。
編輯器特定說明
- 最新的 vscode-go 版本 透過 Go 狀態列的快速選擇選單,可以快速訪問工作區的
go.work
檔案。
- GoLand 支援工作區,並計劃為
go.work
檔案新增語法高亮和程式碼補全功能。
有關在不同編輯器中使用 gopls
的更多資訊,請參閱 gopls
的 文件。
下一步是什麼?
下一篇文章: 何時使用泛型
上一篇文章: Go 如何緩解供應鏈攻擊
部落格索引