教程:多模組工作區入門

本教程將介紹 Go 中多模組工作區的基本概念。透過多模組工作區,您可以告訴 Go 命令您正在同時編寫多個模組的程式碼,並輕鬆構建和執行這些模組中的程式碼。

在本教程中,您將在共享的多模組工作區中建立兩個模組,跨模組進行更改,並檢視這些更改在構建中的結果。

注意: 有關其他教程,請參閱教程

先決條件

  • 安裝 Go 1.18 或更高版本。
  • 一個程式碼編輯工具。 任何文字編輯器都可以。
  • 命令終端。 Go 在 Linux 和 Mac 上的任何終端以及 Windows 上的 PowerShell 或 cmd 中都能很好地工作。

本教程需要 Go 1.18 或更高版本。請確保您已按照 go.dev/dl 上的連結安裝了 Go 1.18 或更高版本。

為您的程式碼建立模組

首先,為您將要編寫的程式碼建立一個模組。

  1. 開啟命令提示符並切換到您的主目錄。

    在 Linux 或 Mac 上

    $ cd
    

    在 Windows 上

    C:\> cd %HOMEPATH%
    

    本教程的其餘部分將顯示 $ 作為提示符。您使用的命令在 Windows 上也適用。

  2. 在命令提示符下,建立一個名為 workspace 的程式碼目錄。

    $ mkdir workspace
    $ cd workspace
    
  3. 初始化模組

    我們的示例將建立一個新的 hello 模組,該模組將依賴於 golang.org/x/example 模組。

    建立 hello 模組

    $ mkdir hello
    $ cd hello
    $ go mod init example.com/hello
    go: creating new go.mod: module example.com/hello
    

    透過使用 go get 新增對 golang.org/x/example/hello/reverse 包的依賴。

    $ go get golang.org/x/example/hello/reverse
    

    在 hello 目錄中建立 hello.go 檔案,內容如下

    package main
    
    import (
        "fmt"
    
        "golang.org/x/example/hello/reverse"
    )
    
    func main() {
        fmt.Println(reverse.String("Hello"))
    }
    

    現在,執行 hello 程式

    $ go run .
    olleH
    

建立工作區

在此步驟中,我們將建立一個 go.work 檔案來指定一個包含該模組的工作區。

初始化工作區

workspace 目錄中,執行

$ go work init ./hello

go work init 命令告訴 go 為工作區建立一個 go.work 檔案,其中包含 ./hello 目錄中的模組。

go 命令生成一個如下所示的 go.work 檔案

go 1.18

use ./hello

go.work 檔案的語法與 go.mod 類似。

go 指令告訴 Go 該檔案應使用哪個版本的 Go 進行解釋。它類似於 go.mod 檔案中的 go 指令。

use 指令告訴 Go,在構建時,hello 目錄中的模組應為主模組。

因此,在 workspace 的任何子目錄中,該模組都將處於活動狀態。

在工作區目錄中執行程式

workspace 目錄中,執行

$ go run ./hello
olleH

Go 命令將工作區中的所有模組都包含為主模組。這允許我們在模組外部引用模組中的包。在模組或工作區外部執行 go run 命令將導致錯誤,因為 go 命令不知道使用哪些模組。

接下來,我們將把 golang.org/x/example/hello 模組的本地副本新增到工作區。該模組儲存在 go.googlesource.com/example Git 儲存庫的一個子目錄中。然後,我們將向 reverse 包新增一個新函式,我們可以使用它而不是 String

下載並修改 golang.org/x/example/hello 模組

在此步驟中,我們將下載包含 golang.org/x/example/hello 模組的 Git 倉庫的副本,將其新增到工作區,然後新增一個新函式,我們將從 hello 程式中使用它。

  1. 克隆倉庫

    在 workspace 目錄中,執行 git 命令克隆倉庫

    $ git clone https://go.googlesource.com/example
    Cloning into 'example'...
    remote: Total 165 (delta 27), reused 165 (delta 27)
    Receiving objects: 100% (165/165), 434.18 KiB | 1022.00 KiB/s, done.
    Resolving deltas: 100% (27/27), done.
    
  2. 將模組新增到工作區

    Git 倉庫已克隆到 ./examplegolang.org/x/example/hello 模組的原始碼位於 ./example/hello。將其新增到工作區

    $ go work use ./example/hello
    

    go work use 命令將一個新模組新增到 go.work 檔案。它現在看起來像這樣

    go 1.18
    
    use (
        ./hello
        ./example/hello
    )
    

    工作區現在包括 example.com/hello 模組和 golang.org/x/example/hello 模組,後者提供了 golang.org/x/example/hello/reverse 包。

    這將允許我們使用我們將在 reverse 包的副本中編寫的新程式碼,而不是使用 go get 命令下載的模組快取中的版本。

  3. 新增新函式。

    我們將向 golang.org/x/example/hello/reverse 包新增一個反轉數字的新函式。

    workspace/example/hello/reverse 目錄中建立一個名為 int.go 的新檔案,其中包含以下內容

    package reverse
    
    import "strconv"
    
    // Int returns the decimal reversal of the integer i.
    func Int(i int) int {
        i, _ = strconv.Atoi(String(strconv.Itoa(i)))
        return i
    }
    
  4. 修改 hello 程式以使用該函式。

    修改 workspace/hello/hello.go 的內容,使其包含以下內容

    package main
    
    import (
        "fmt"
    
        "golang.org/x/example/hello/reverse"
    )
    
    func main() {
        fmt.Println(reverse.String("Hello"), reverse.Int(24601))
    }
    

在工作區中執行程式碼

在 workspace 目錄中,執行

$ go run ./hello
olleH 10642

Go 命令在 go.work 檔案指定的 hello 目錄中找到命令列指定的 example.com/hello 模組,並使用 go.work 檔案類似地解析 golang.org/x/example/hello/reverse 匯入。

go.work 可用於替代新增 replace 指令來處理多個模組。

由於這兩個模組在同一個工作區中,因此可以輕鬆地在一個模組中進行更改並在另一個模組中使用。

後續步驟

現在,要正確釋出這些模組,我們需要釋出 golang.org/x/example/hello 模組,例如在 v0.1.0。這通常透過標記模組的版本控制倉庫中的提交來完成。有關更多詳細資訊,請參閱 模組釋出工作流文件。釋出完成後,我們可以增加 hello/go.mod 中對 golang.org/x/example/hello 模組的要求。

cd hello
go get golang.org/x/example/hello@v0.1.0

這樣,go 命令就可以正確地解析工作區外部的模組。

瞭解更多關於工作區的資訊

除了我們在教程前面看到的 go work init 之外,go 命令還有幾個用於處理工作區的子命令

  • go work use [-r] [dir]use 指令新增到 go.work 檔案中 dir(如果存在),如果引數目錄不存在,則刪除 use 目錄。-r 標誌遞迴地檢查 dir 的子目錄。
  • go work edit 類似地編輯 go.work 檔案,就像 go mod edit 一樣
  • go work sync 將工作區的構建列表中的依賴項同步到工作區的每個模組中。

有關工作區和 go.work 檔案的更多詳細資訊,請參閱 Go 模組參考中的 工作區