← 返回文章列表

golang學習記錄(12)

區分 package 與 module,整理 go.mod、go.sum、依賴命令、GOPROXY 和 replace 的正確用法。

1、package 和 module 先分開

package 是組織 Go 原始碼的單位;module 則是一組由 go.mod 管理的包。一個 module 可以有很多個 package,不是每個目錄都要放一個 go.mod。可以對照官方的模組組織示例看目錄和匯入路徑的關係。

同一目錄中的普通 Go 檔案通常屬於同一個包,可以直接使用包內名字。外部測試可以用 xxx_test 包,這是常見的例外。main 包的 main() 是可執行程式入口。

比如最簡單的專案:

hello/
├── go.mod
├── main.go
└── greeting/
    └── greeting.go

在 hello 目錄執行:

go mod init example.com/hello

greeting/greeting.go:

package greeting

func Message() string {
	return "hello, Go"
}

main.go:

package main

import (
	"example.com/hello/greeting"
	"fmt"
)

func main() {
	fmt.Println(greeting.Message())
}

在專案根目錄執行 go run .,輸出 hello, Go。匯入路徑由 module 路徑和子目錄組成,不是簡單寫一個本地磁碟路徑。

2、import 的幾種方式

普通匯入以後,用包名訪問匯出的名字。需要避開重名時,可以加別名:

import myjson "encoding/json"

還有兩種寫法:import _ "包路径" 用於僅執行初始化等副作用;import . "包路径" 會把匯出名字放進當前檔案作用域。後一種容易讓名字來源變得不清楚,普通業務程式碼通常不需要它。

完整規則可以對照 Go 語言規範中的包與匯入。

3、go.mod 和 go.sum

go.mod 記錄 module 路徑、Go 版本要求和依賴等資訊。go.sum 儲存下載模組內容的校驗記錄,它不是傳統意義上覆蓋全部依賴選擇邏輯的鎖檔案。

這兩個檔案通常都應提交。具體依賴如何選擇以及各個指令的意義,以 Go Modules Reference為準。

原有模組記錄

4、常用指令分別幹什麼?

按官方依賴管理說明,先區分修改依賴與安裝工具。

指令用途
go mod init 模块路径建立模組
go mod tidy按程式碼和測試需要補充、清理依賴記錄
go get 包路径@版本在當前模組中調整依賴版本
go mod download下載模組依賴
go list -m all檢視當前模組依賴列表
go mod graph檢視模組依賴關係
go mod verify檢查本地模組快取是否被改動
go install 工具路径@版本安裝指定版本的可執行工具

現在安裝 CLI 工具,通常使用 go install ...@版本,不要再把 go get 當成通用工具安裝命令。模組有變化後,跑一遍 go mod tidy 和 go test ./...,並看一下 diff,確認沒有無意升級一大批依賴。

5、GOPROXY

先檢視當前值:

go env GOPROXY

需要時可以設定,例如:

go env -w GOPROXY=https://goproxy.cn,direct

它修改的是 Go 工具鏈的持久配置,不只作用於當前終端。選代理時也要考慮自己的網路環境和組織要求。

逗號分隔的代理列表通常在 404/410 時嘗試下一個來源,不表示任何失敗都一定回退;這個區別在排查網路問題時很重要,見模組下載規則。

原有 GOPROXY 設定記錄

6、replace 的正確寫法

replace 可以把某個模組替換為本地目錄或另一個模組版本。它是 go.mod 中的指令;命令列編輯它,用的是 go mod edit -replace,沒有 go mod replace 這個命令。

比如本地同時開發兩個模組:

module example.com/hello

go 1.24

require example.com/common v0.0.0

replace example.com/common => ../common

也可以在專案目錄執行:

go mod edit -replace=example.com/common=../common
go mod tidy

被替換的目錄本身也應是一個模組。replace 不會憑空新增一個依賴;而且主模組裡的本地替換不會自動替使用你這個庫的人生效。發布前檢查本地路徑替換是否還應該保留。相關規則見 go.mod 的 replace 說明。

7、平時怎麼保持專案乾淨?

原始碼使用 gofmt,提交前跑測試;只引入用得到的依賴。一個新的依賴不只是少寫幾行程式碼,還意味著版本更新和維護工作。

原來的編碼規範截圖保留作記錄,實際規則優先看官方說明和當前專案約定。

編碼規範舊記錄 1

編碼規範舊記錄 2

編碼規範舊記錄 3

關於這篇文章的日期

保留舊站原始文章標註的日期;實際開始寫作的時間可能更早。

原始日期: 2024-10-20 15:01:03 +0800

同一系列 · Go 基礎學習

上一篇golang學習記錄(11) ←下一篇golang學習記錄(13) →