教學手冊:使用多模組工作區入門

本教學手冊介紹 Go 中多模組工作區的基礎知識。使用多模組工作區,您可以告訴 Go 指令您同時撰寫多個模組中的程式碼,並在這些模組中輕鬆地建置和執行程式碼。

在本教學手冊中,您將在共享的多模組工作區中建立兩個模組,修改這些模組,並在建置中查看這些修改的結果。

注意:有關其他教學手冊,請參閱 教學手冊

先決條件

本教學手冊需要 go1.18 或更新的版本。請確定您已透過 go.dev/dl 上的連結,將 Go 安裝在 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 為包含 ./hello 目錄中的模組的工作區建立一個 go.work 檔案。

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. 複製儲存庫

    從工作區目錄執行 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))
    }
    

在工作空間中執行程式碼

從工作空間目錄中執行

$ go run ./hello
olleH 10642

Go 指令會在 ```hello``` 目錄中尋找命令列中指定的 ```example.com/hello``` 模組(由 ```go.work``` 檔案指定),並會使用 ```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``` 檔案的更多詳細資訊。