go?mod的使用方法小結(jié)
前言
對于多個項目來說,把所有的源碼都放在GOPATH下的src目錄下非常的不方便。golang給我們提供了一個叫go mod的命令來脫離src目錄,方便我們管理go項目。go mod 是go官方提供的go版本管理的一個方案,目前1.15已經(jīng)可用于生產(chǎn)環(huán)境。
1.go modules的基本介紹
1.1 提供的命令
在go環(huán)境的shell中執(zhí)行go mod help查看命令和說明。
Usage:
go mod <command> [arguments]
The commands are:
download download modules to local cache
edit edit go.mod from tools or scripts
graph print module requirement graph
init initialize new module in current directory
tidy add missing and remove unused modules
vendor make vendored copy of dependencies
verify verify dependencies have expected content
why explain why packages or modules are needed
1.2 提供的環(huán)境變量
用go env查看go的環(huán)境變量,在所有g(shù)o提供的環(huán)境變量中,有一個是和go mod相關(guān)的。
GO111MODULE="on" GOPROXY="https://goproxy.cn,direct" GONOPROXY="git.example.com,x1" GONOSUMDB="git.example.com,x1" GOPATH="/home/go-project/" GOPRIVATE="git.example.com,x1" GOSUMDB="sum.golang.org" # 省略其余環(huán)境變量...
1.2.1 說明
1) GO111MODULE
go語言提供GO111MODULE環(huán)境變量三個值,用于GO111MODULE的開關(guān):
- auto:只要項目中包含了
go.mod這個文件,就啟動該項目的go modules,在 Go1.11 至 Go1.14 中仍然是默認(rèn)值。 - on:啟動
go modules - off:關(guān)閉
go modules
2) GOPROXY
go env中默認(rèn)的代理是GOPROXY="https://proxy.golang.org,direct",但是在國內(nèi)是無法訪問的,這里需要設(shè)置成國內(nèi)的代理地址GOPROXY="https://goproxy.cn,direct"
GOPROXY的值是一個以英文逗號 “,” 分割的 Go 模塊代理列表,允許設(shè)置多個模塊代理,假設(shè)你不想使用,也可以將其設(shè)置為 “off” ,這將會禁止 Go 在后續(xù)操作中使用任何 Go 模塊代理。
direct
實際上 “direct” 是一個特殊指示符,用于指示 Go 回源到模塊版本的源地址去抓?。ū热?GitHub 等),場景如下:當(dāng)值列表中上一個 Go 模塊代理返回 404 或 410 錯誤時,Go 自動嘗試列表中的下一個,遇見 “direct” 時回源,也就是回到源地址去抓取,而遇見 EOF 時終止并拋出類似 “invalid version: unknown revision…” 的錯誤。
在cmd中執(zhí)行set GO111MODULE=on

3)GONOPROXY/GONOSUMDB/GOPRIVATE
這三個環(huán)境變量都是用在當(dāng)前項目依賴了私有模塊,例如像是你公司的私有 git 倉庫,又或是 github 中的私有庫,都是屬于私有模塊,都是要進(jìn)行設(shè)置的,否則會拉取失敗。對于一些自己的私有模塊代碼,需要在GOPRIVATE上設(shè)置,在拉取時會提示輸入用戶名和密碼。
可以設(shè)置多個,用英文的逗號分隔開;或者用通配符等
go env -w GOPRIVATE="git.example.com,github.com/eddycjy/mquote" go env -w GOPRIVATE="*.example.com" # 通配example.com的域名
2.go modules的基本使用
開啟go modules后,就可以創(chuàng)建項目并且生成mod文件,來管理項目的所有依賴了。以下是go env環(huán)境的配置:
GO111MODULE="auto" GOARCH="amd64" GOBIN="/go/bin/" GOCACHE="/root/.cache/go-build" GOENV="/root/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/go-project/" GOPRIVATE="" GOPROXY="https://goproxy.cn,direct" GOROOT="/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/go/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build940953411=/tmp/go-build -gno-record-gcc-switches"
設(shè)置了GOPATH為/home/go-project/,并且代理指向了國內(nèi)的代理地址,防止國外鏡像無法訪問的情況。
2.1 初始化項目
在$GOPATH目錄下創(chuàng)建一個新的項目example.com/mycount/hello,example.com模擬github.com,mycount模擬賬號,hello是最終的項目名稱。目錄和文件結(jié)構(gòu):

2.1.1 初始化.mod文件
在hello目錄下執(zhí)行go mod init example.com/mycount/hello初始化hello項目的mod文件,如下:

執(zhí)行完初始化操作后生成了一個go.mod的文件,里面只記錄了2行:

- module:用于定義當(dāng)前項目的模塊路徑
- go:用于標(biāo)識當(dāng)前模塊的 Go 語言版本,值為初始化模塊時的版本,目前來看還只是個標(biāo)識作用
2.1.2 簡單一個示例
在hello目錄下寫一個main.go的文件,里面用了一個第三方的庫。
package main
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/json-iterator/go"
)
type resp struct {
Status int `json:"status"`
Message string `json:"message"`
}
func main() {
router := gin.Default()
router.GET("/", hello())
if err := router.Run(":6060"); err != nil {
panic(err)
}
}
func hello() gin.HandlerFunc {
return func(context *gin.Context) {
strResp, _ := jsoniter.MarshalToString(resp{
Status: http.StatusOK,
Message: "success",
})
context.String(http.StatusOK, strResp)
}
}
在hello目錄下執(zhí)行go get命令,拉取依賴庫:

拉取依賴之后生成了一個go.mod和go.sum文件,go.mod文件:

go.sum的內(nèi)容:

同時在$GOPATH目錄下多了一個pkg文件,里面有拉取的文件依賴。這個文件是一個全局的緩存,
2.1.3 go modules的go get
在拉取項目依賴時,你會發(fā)現(xiàn)拉取的過程總共分為了三大步,分別是 finding(發(fā)現(xiàn))、downloading(下載)以及 extracting(提?。?, 并且在拉取信息上一共分為了三段內(nèi)容:

需要注意的是,所拉取版本的 commit 時間是以UTC時區(qū)為準(zhǔn),而并非本地時區(qū),同時我們會發(fā)現(xiàn)我們 go get 命令所拉取到的版本是 v0.0.0,這是因為我們是直接執(zhí)行 go get -u 獲取的,并沒有指定任何的版本信息,由 Go modules 自行按照內(nèi)部規(guī)則進(jìn)行選擇。

那么我想選擇具體版本應(yīng)當(dāng)如何執(zhí)行呢,如下:

3.使用go mod發(fā)布自己的包
3.1 發(fā)布公開的包
公開的發(fā)布包無需修改go env中的一些環(huán)境變量,默認(rèn)的環(huán)境變量即可。
3.1.1 包的實現(xiàn)
假設(shè)我們有一個模塊需要提供給第三方使用,并且這個包是發(fā)布在了gittee上,假設(shè)我在gitee上得賬號是gitee.com\luciferofwg。我們后期會根據(jù)迭代或者功能維護(hù)版本,每當(dāng)有更新或者升級的時候就發(fā)布最新的版本,版本遵循語義化版本定義。什么是語義化版本
這個包中包含一個函數(shù),用于打印一句話,如下所示:
// hello.go
package hello
import "fmt"
func SayHello() {
fmt.Println("hello world")
}
在GOPATH下新建目錄hello,在命令行下進(jìn)入hello目錄,執(zhí)行go mod init來生成go mod文件,如下:

生成的包名為gitee.com/luciferofwg/hello,后期在引用這個包時就import 這個包名。
將hello倉庫提交到gitee上,完成發(fā)布包的第一個階段。
3.1.2 包的發(fā)布
經(jīng)過上一步驟,在倉庫中就有了一個名為hello的公開倉庫,如下:

假如我們認(rèn)為這個版本是穩(wěn)定可靠的,這時候我們需要發(fā)布一個可以使用的版本,gitee發(fā)布的流程如下:
點擊倉庫中右側(cè)的創(chuàng)建按鈕,在彈出的頁面中創(chuàng)建發(fā)行版本號,填寫完畢后點擊創(chuàng)建發(fā)行版本完成發(fā)布。
圖1 創(chuàng)建發(fā)行版本

圖2 發(fā)行版本信息

圖3 已創(chuàng)建的發(fā)行版本

到此我們發(fā)行了一個版本為v1.0.4的版本。
3.1.3 包的使用
對于已經(jīng)發(fā)行的包,這里介紹如何使用它。首先定義一個名為test的包,因為test為調(diào)用的程序,因此我們初始化mod時直接按照程序的名字初始化,即:go mod test,完成初始化。如下:

在test目錄下編寫如下代碼:
package main
import "gitee.com/luciferofwg/hello"
func main() {
hello.SayHello()
}
然后再命令行中執(zhí)行go mod tidy整理go mod,此時go mod會根據(jù)程序包的引用關(guān)系按照包名從互聯(lián)網(wǎng)上拉去對應(yīng)的包。執(zhí)行完成后go.mod如下:

運行的結(jié)果:

需要注意的是:
默認(rèn)拉去的是最新的發(fā)布版本,如果想制定版本,只需要修改go.mod中require最后面的版本號即可。如何修改go.mod參考go help mod命令的edit項。
3.2 發(fā)布私有包
3.2.1 go env環(huán)境變量和git配置的修改
1.go env環(huán)境變量的修改
私有包和公開包的區(qū)別最大的區(qū)別是權(quán)限的和git拉去包的過程,這時候需要對go env中的一些參數(shù)修改。涉及到的一些參數(shù)GOINSECURE,GONOPROXY,GONOSUMDB,含義:GOINSECURE:如果代碼倉庫是自己搭建的,沒有“合法”的證書,則需要配置這個信息GONOPROXY:在這個變量中配置的域名或者倉庫地址不會走代理(我們在前面設(shè)置了cn的代理)GONOSUMDB:1.15后會對包進(jìn)行校驗,此處的配置和GONOPROXY的含義一樣
看一下我們的go env變量,之前已經(jīng)修改過了,內(nèi)容如下:

注:
windows下修改時直接將上述的配置增加系統(tǒng)的環(huán)境變量即可,linux下在bash的配置文件中修改(具體修改可以自行搜索)。
2.git配置的修改
由于是私有的包,拉去時需要獲取拉去的權(quán)限,默認(rèn)的https或者h(yuǎn)ttp的方式需要密碼。如果我們本地已經(jīng)配置了對應(yīng)的gitee上的私鑰,且已經(jīng)在gitee對應(yīng)的賬戶上配置了權(quán)限,那么我們就可以通過git@xxx的方式訪問私有的倉庫。
打開本地git的配置,windows下是c:\\user\\用戶名\\.bashconfig文件,打開這個文件。增加以下代碼:
[url "git@gitee.com:"]insteadof = https://gitee.com
表示訪問https://gitee.com的過程替換為git@gitee.com:,即通過bash就可以訪問私有庫了。
3.2.2 私有包的實現(xiàn)
1.私有包實現(xiàn)
我們創(chuàng)建一個私有的倉庫,名為hi,包含一個函數(shù)SayHello,打印hello world。
同樣的,創(chuàng)建go.mod,實現(xiàn)SayHello函數(shù),推送到gitee。
圖1 私有倉庫hi

2.函數(shù)和源碼
// hi包的SayHello函數(shù)
package hi
import "fmt"
func SayHello() {
fmt.Println("hi, world")
}
hi包的go.mod

3.2.3 私有包的發(fā)布
根據(jù)上述的源碼,使用同樣的方式發(fā)布版本。
圖1 發(fā)布的版本1.0.0

3.2.4 私有包的引用
如果已經(jīng)配置了go env的參數(shù)和git配置,使用的過程和公開包的使用是一樣的?;谠瓉淼陌姹?,增加了一個hi包的函數(shù)引用和導(dǎo)入,在test目錄下執(zhí)行go mod tidy,就會自動拉取發(fā)布的包了。
package main
import (
"gitee.com/luciferofwg/hello"
"gitee.com/luciferofwg/hi"
)
func main() {
hello.SayHello()
hi.SayHello()
}
test程序的go.mod如下:

到此這篇關(guān)于go mod的使用方法小結(jié)的文章就介紹到這了,更多相關(guān)go mod使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang 經(jīng)典校驗庫 validator 用法解析
這篇文章主要為大家介紹了Golang 經(jīng)典校驗庫 validator 用法解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Go實現(xiàn)將任何網(wǎng)頁轉(zhuǎn)化為PDF
在許多應(yīng)用場景中,可能需要將網(wǎng)頁內(nèi)容轉(zhuǎn)化為?PDF?格式,使用Go編程語言,結(jié)合一些現(xiàn)有的庫,可以非常方便地實現(xiàn)這一功能,下面我們就來看看具體實現(xiàn)方法吧2024-11-11
golang channel讀取數(shù)據(jù)的幾種情況
本文主要介紹了golang channel讀取數(shù)據(jù)的幾種情況,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
golang通過context控制并發(fā)的應(yīng)用場景實現(xiàn)
這篇文章主要介紹了golang通過context控制并發(fā)的應(yīng)用場景實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
go如何優(yōu)雅關(guān)閉Graceful?Shutdown服務(wù)
這篇文章主要為大家介紹了go優(yōu)雅關(guān)閉Graceful?Shutdown服務(wù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05

