詳解Go Modules 依賴解決

Go Modules是什么?
Go Modules 是 Go 語言的依賴解決方案。
Go Modules 目前集成在 Go 的工具鏈中,只要安裝了 Go,自然就可以使用 Go modules,Go modules 解決了 Go1.11 前的幾個(gè)常見問題:
(1)Go 語言長久以來的依賴管理問題。
(2)“淘汰”現(xiàn)有的 GOPATH 的使用模式
(3)統(tǒng)一社區(qū)中的其它的依賴管理工具(提供遷移功能)
GOPATH 的工作模式
GOPATH下有三個(gè)文件夾:
![]()
bin:代表已經(jīng)編譯過的 go 語言的所有可執(zhí)行程序。
pkg:存儲(chǔ)默認(rèn)文件,加快編譯速度。
src:所有的源文件。
GOPATH 的弊端:
(1)無版本控制概念。無法知道當(dāng)前拉取的是哪個(gè)版本,也無法指定拉取自己的期望版本。
(2)無法同步一致第三方版本號。無法保證自己的版本與其他人的版本一致。
(3)無法指定當(dāng)前項(xiàng)目引用的第三方版本號。
Go Modules模式
go mod命令
通過:go mod help
可以查看go mod命令

| 命令 | 作用 |
|---|---|
| go mod init | 生成go.mod文件 |
| go mod download | 下載go.mod 文件中指明的所有依賴 |
| go mod tidy | 整理現(xiàn)有的依賴 |
| go mod graph | 查看現(xiàn)有的依賴結(jié)構(gòu) |
| go mod edit | 編輯 go.mod 文件 |
| go mod vendor | 導(dǎo)出項(xiàng)目所有的依賴到vendor目錄 |
| go mod verify | 校驗(yàn)一個(gè)模塊是否被篡改過 |
| go mod why | 查看為什么需要依賴某模塊 |
go mod環(huán)境變量
通過 go env 命令查看環(huán)境變量:

(1)GO111MODULE
Go語言提供了GO111MODULE這個(gè)環(huán)境變量來作為Gomodules的開關(guān),其允許設(shè)置以下參數(shù):
- auto:只要項(xiàng)目包含了go.mod文件的話啟期Go modules,目前在Go1.11至Go1.14中仍然是默認(rèn)值。
- on:啟用Gomodules,推薦設(shè)置,將會(huì)是未來版本中的默認(rèn)值。
- off:禁用Go modules,不推薦設(shè)置。
可以通過來設(shè)置:go env -w G0111MODULE=on
(2)GOPROXY
這個(gè)環(huán)境變量主要是用于設(shè)置Go模塊代理(Gomoduleproxy),其作用是用于使Go在后續(xù)拉取模塊版本時(shí)直接通過鏡像站點(diǎn)來快速拉取。
GOPROXY 的默認(rèn)值是:https://proxy.golang.org,direct
proxy·golang.org國內(nèi)訪問不了,需要設(shè)置國內(nèi)的代理。
- 阿里云:
https://mirrors.aliyun.com/goproxy/ - 七牛云:
https://goproxy.cn,direct
direct:用于指示Go回源到模塊版本的源地址去抓取(比如GitHub等)
(3)GOSUMDB
它的值是一個(gè)Go checksum database,用于在拉取模塊版本時(shí)(無論是從源站拉取還是通過Gomodule proxy拉?。?strong>保證拉取到的模塊版本數(shù)據(jù)未經(jīng)過篡改,若發(fā)現(xiàn)不一致,也就是可能存在篡改,將會(huì)立即中止。
GOSUMDB 的默認(rèn)值為:sum.golang.org,在國內(nèi)也是無法訪問的,但是GOSUMDB 可以被Go模塊代理所代理。
因此我們可以通過設(shè)置GOPROXY來解決,而先前我們所設(shè)置的模塊代理goproxy.cn就能支持代理sum.golang.org,所以這一個(gè)問題在設(shè)置GOPROXY后,你可以不需要過度關(guān)心。
(4)GONOPROXY、GONOSUMDB、GOPRIVATE
- GONOPROXY:通過設(shè)置GOPRIVATE即可
- GONOSUMDB:通過設(shè)置GOPRIVATE即可
- GOPRIVATE:
go env -w GOPRIVATE="git.example.com,github.com/aceld/zinx:表示git.example.com和github.com/aceld/zinx是私有倉庫,不會(huì)進(jìn)行GOPROXY下載和校驗(yàn)。go evn -w GOPRIVATE="*example.com":表示所有模塊路徑為example.com的子域名,比如
git.example.com或者h(yuǎn)ello.example.com都不進(jìn)行GOPROXY下載和校驗(yàn)。
Go Modules初始化項(xiàng)目
開啟Go Modules
go env -w GO111MODULE=on
初始化項(xiàng)目
創(chuàng)建項(xiàng)目目錄:在 E 盤下的 go_modules 文件夾下創(chuàng)建項(xiàng)目目錄為 modules_test。
執(zhí)行 Go modules 初始化,起一個(gè)當(dāng)前項(xiàng)目的模塊名稱:go init github.com/go_modules/modules_test

初始化完成后,生成了 go.mod 文件:

打開 go.mod 文件:

在項(xiàng)目目錄下編寫源代碼,創(chuàng)建 main.go 文件
package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"github.com/aceld/zinx/ziface"
)
//ping test 自定義路由
type PingRouter struct {
znet.BaseRouter
}
//Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
//先讀取客戶端的數(shù)據(jù)
fmt.Println("recv from client : msgId=", request.GetMsgID(),
", data=", string(request.GetData()))
//再回寫ping...ping...ping
err := request.GetConnection().SendBuffMsg(0, []byte("ping...ping...ping"))
if err != nil {
fmt.Println(err)
}
}
func main() {
//1 創(chuàng)建一個(gè)server句柄
s := znet.NewServer()
//2 配置路由
s.AddRouter(0, &PingRouter{})
//3 開啟服務(wù)
s.Serve()
}
當(dāng)前的 go_modules/modules_test 項(xiàng)目,依賴一個(gè)叫g(shù)ithub.com/aceld/zinx庫的,znet和ziface只是zinx的兩個(gè)模塊。
在 go_modules/modules_test 下執(zhí)行:go get github.com/aceld/zinx/znet
此時(shí) go.mod 文件被修改,并生成了 go.sum 文件:

(1)go.mod 文件:

- module:用于定義當(dāng)前項(xiàng)目的模塊路徑
- go:標(biāo)識當(dāng)前Go版本
- require:當(dāng)前項(xiàng)目依賴的一個(gè)特定的必須版本
// indirect:表示該模塊為間接依賴。項(xiàng)目直接依賴的是 znet 包,間接依賴 zinx 包。
(2)go.sum 文件
go.sum 文件詳細(xì)羅列了當(dāng)前項(xiàng)目直接或間接依賴的所有模塊版本,并寫明了模塊版本的 SHA-256 哈希值以備 Go 在今后的操作中保證項(xiàng)目所依賴的那些模塊版本不會(huì)被篡改。

一個(gè)模塊路徑可能有如下兩種:
h1:hash情況:是 Go modules 將目標(biāo)模塊版本的 zip 文件開包后,針對所有包內(nèi)文件依次進(jìn)行 hash,然后再把它們的 hash 結(jié)果按照固定格式和算法組成總的 hash 值。
![]()
go.mod hash情況:對 go.mod 文件做的hash
![]()
h1 hash 和 go.mod hash 兩者,要不就是同時(shí)存在,要不就是只存在 go.mod hash。當(dāng) Go 認(rèn)為肯定用不到某個(gè)模塊版本的時(shí)候就會(huì)省略它的 h1 hash,就會(huì)出現(xiàn)不存在 h1 hash,只存在 go.mod hash 的情況。
修改模塊的版本依賴關(guān)系
當(dāng)前依賴的zinx版本是最新版本:

如果想要使用以前的舊版本,可以通過在項(xiàng)目目錄下執(zhí)行:
go mod edit -replace=zinx@v1.2.7=zinx@v0.0.0-20200221135252-8a8954e75100
![]()
此時(shí),go mod文件:

replace關(guān)鍵字:用于將一個(gè)模塊版本替換為另外一個(gè)模塊版本。
到此這篇關(guān)于Go Modules 依賴解決的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Go Modules 依賴內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
重學(xué)Go語言之基礎(chǔ)數(shù)據(jù)類型詳解
Go語言有非常強(qiáng)大的數(shù)據(jù)類型系統(tǒng),其支持的數(shù)據(jù)類型大體上可分為四類:基礎(chǔ)數(shù)據(jù)類型、引用數(shù)據(jù)類型、接口類型、復(fù)合類型。本文就來講講它們各自的用法吧2023-02-02
基于微服務(wù)框架go-micro開發(fā)gRPC應(yīng)用程序
這篇文章介紹了基于微服務(wù)框架go-micro開發(fā)gRPC應(yīng)用程序的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
Go項(xiàng)目中使用Casbin實(shí)現(xiàn)RBAC權(quán)限管理教程
本文主要介紹了Go項(xiàng)目中使用Casbin實(shí)現(xiàn)RBAC權(quán)限管理教程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-01-01
Go語言數(shù)據(jù)庫編程GORM 的基本使用詳解
GORM是Go語言流行的ORM框架,封裝database/sql,支持自動(dòng)遷移、關(guān)聯(lián)、事務(wù)等,提供CRUD、條件查詢、鉤子函數(shù)、日志等功能,簡化數(shù)據(jù)庫操作,提升開發(fā)效率,本文給大家介紹Go語言GORM使用,感興趣的朋友一起看看吧2025-06-06
Go語言使用SQLite實(shí)現(xiàn)本地存儲(chǔ)的示例詳解
在開發(fā)工具類軟件、桌面應(yīng)用或者移動(dòng)端時(shí),我們經(jīng)常需要一個(gè)輕量級數(shù)據(jù)庫來做本地存儲(chǔ),本文將帶你一步步用 Go 搭建一個(gè) SQLite 本地存儲(chǔ)的示例,希望對大家有所幫助2025-08-08

