日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

一文詳細(xì)了解 Go Module

 

1 速覽

在正式了解Golang Modules之前,我們先速覽一下其使用方式。

在$GOPATH之外的任意地方,創(chuàng)建一個文件夾:

$ mkdir -p /tmp/hello
$ cd /tmp/hello

然后初始化一個新的Module:

$ go mod init github.com/olzhy/hello

輸出:

go: creating new go.mod: module github.com/olzhy/hello

go.mod內(nèi)容為:

module github.com/olzhy/hello
go 1.12

然后寫一段代碼:

$ cat < hello.go
package main
import (
 "fmt"
 "github.com/olzhy/quote"
)
func main() {
 fmt.Println(quote.Hello())
}
EOF

build一下:

$ go build
go: finding github.com/olzhy/quote latest
go: downloading github.com/olzhy/quote v0.0.0-20190510033103-5cb7d4598cfa
go: extracting github.com/olzhy/quote v0.0.0-20190510033103-5cb7d4598cfa

go.mod內(nèi)容為:

module github.com/olzhy/hello
go 1.12
require github.com/olzhy/quote v0.0.0-20190510033103-5cb7d4598cfa

可以看到,其會從https://github.com/olzhy/quote master分支拉取最新提交5cb7d4598cfa。

該依賴工程非Module管理模式,其僅有兩個文件:

hello.go
README.md

現(xiàn)在給依賴工程打一個TAG,名為v1.0.0。

然后hello工程更新依賴:

$ go get -u
go: finding github.com/olzhy/quote v1.0.0
go: downloading github.com/olzhy/quote v1.0.0
go: extracting github.com/olzhy/quote v1.0.0

查看go.mod內(nèi)容為:

module github.com/olzhy/hello
go 1.12
require github.com/olzhy/quote v1.0.0

如下為使用Golang Module后的日常工作流。

每日工作流:

  • a)源碼根據(jù)需要加入包引入語句;
  • b)標(biāo)準(zhǔn)命令,如go build及go test等會自動更新go.mod并下載依賴包;
  • c)當(dāng)需要特定版本時,可以使用諸如go get [email protected],go get foo@master,go get foo@e3702bed2命令或直接編輯go.mod文件。

其它通用命令:

  • a)go list -m all 查看一次構(gòu)建使用的直接及間接依賴的最終版本;
  • b)go list -u -m all 查看直接及間接依賴的可用的小版本或補丁版本更新;
  • c)go get -u 或 go get -u=patch 將直接與間接依賴更新為最新小版本或補丁版本;
  • d)go build ./... 或 go test ./... 構(gòu)建或測試模塊中的所有包;
  • e)go mod tidy 從go.mod清理不再使用的包;
  • f)go mod edit -replace [email protected]=../foo 替換依賴為本地復(fù)制或指定版本;
  • g)go mod vendor 轉(zhuǎn)換為vendor依賴方式。

2 概念

2.1 模塊

Module是一組相關(guān)Go package的集合,其作為一個單獨的單元來版本化。

Module記錄精確的依賴項,提供可重復(fù)的構(gòu)建。

通常,一個版本控制倉庫僅包含一個Module(支持單倉庫多Module,但其會比單倉庫單Module復(fù)雜很多)。

倉庫、模塊與包的關(guān)系:

  • a)一個倉庫包含一個或多個模塊;
  • b)一個模塊包含一個或多個包;
  • c)一個包在一個文件夾包含一個或多個.go文件。

模塊必須以語義學(xué)版本命名,格式為v(主版本).(小版本).(補丁),諸如v0.1.0、v1.2.3,v1.5.0-rc.1等。

模塊由一組源文件樹在根目錄定義一個go.mod文件,模塊源碼可以位于GOPATH之外,有如下原語module,require,replace,exclude。

如下為github.com/olzhy/hello模塊的go.mod文件示例內(nèi)容:

module github.com/olzhy/hello
require (
 github.com/some/dependency v1.2.3
 github.com/another/dependency/v4 v4.0.0
)

可以看到,一個模塊通過module原語聲明模塊ID,其標(biāo)識模塊路徑。該模塊下某一個包的被引用路徑由該模塊路徑與自go.mod所在路徑起一直到包的路徑止的相對路徑共同決定。

如,一個模塊在go.mod聲明其ID為example.com/my/module,那么引用該模塊下mypkg包的代碼為:

import "example.com/my/module/mypkg"

2.2 版本選擇

若源碼中增加了go.mod中未require的新的依賴包,絕大多數(shù)諸如go build,go test命令會自動找到對應(yīng)的包并在go.mod中采用require原語加入該直接依賴的最高版本

例如,您依賴的模塊M的帶標(biāo)簽的發(fā)布版本為v1.2.3,那么您的go.mod會新加入require M v1.2.3這一行語句,意味著依賴模塊M所允許的版本>= v1.2.3并< v2(v2被認(rèn)為與v1不兼容)。 最小版本選擇算法用于對一次構(gòu)建的所有模塊選擇版本,對于每個模塊,采用該算法選擇的版本為語義學(xué)最高版本

下面舉個例子:

若您依賴的模塊A依賴D(require D v1.0.0),而您依賴的模塊B同樣依賴D(require D v1.1.1),然后,最小版本選擇(選擇最高的版本)將會選擇v1.1.1版本的D。而選擇v1.1.1版本的D是一致的,即使將來發(fā)布了v1.2.0版本的D。

這樣即可保持100%可重復(fù)構(gòu)建。當(dāng)然您也可以手動升級D為最新可用版本或者指定其為其它版本。

查看所選模塊版本列表(包括間接依賴),可以使用:

go list -m all

2.3 語義學(xué)版本引用

Go多年來推薦的包版本化方式:

開放使用的包在演進(jìn)時應(yīng)保持向后兼容的準(zhǔn)則,Go 1兼容性準(zhǔn)則即是一個好的參考。不要移除已導(dǎo)出的名稱,若要加一個新功能,需加一個新接口,不要改動老接口名。實在需要推倒之前的,請創(chuàng)建一個新包,以新的路徑而被引用。

最后一句很重要,若破壞了兼容性,需更改包的引用路徑。

對Go 1.11模塊而言,引用兼容性準(zhǔn)則可以概述為:

若新包沿用舊包的引用路徑,新包必須向后兼容舊包。

參考語義學(xué)版本命名規(guī)則,當(dāng)一個原始為v1或v1以上的包發(fā)生了不兼容變更,該包需要更改主版本。

所以,根據(jù)引用兼容性準(zhǔn)則及語義學(xué)版本命名規(guī)則(合稱為語義學(xué)版本引用),主版本需要包含在引用路徑內(nèi)。這樣即可保障不兼容的主版本升級時,引用路徑即會改變。

根據(jù)語義學(xué)版本引用規(guī)則,選用Go Module的代碼必須遵守如下規(guī)則:

  • a)語義學(xué)版本命名;
  • b)若一個Module的版本為v2及以上,模塊的主版本必須包含在模塊路徑及引用路徑中(例如,聲明方:module github.com/my/mod/v2,引用方:require github.com/my/mod/v2 v2.0.0,包引用處:import "github.com/my/mod/v2/mypkg");
  • c)例外,若模塊主版本為v0或v1,模塊路徑及引用路徑無須包含主版本。

通常來講,引用路徑不同的包是兩個全然不同的包(如math/rand和crypto/rand是兩個不同的包)。同樣,包含不同主版本的引用路徑所標(biāo)識的包亦是兩個不同的包。因此,example.com/my/mod/mypkg與example.com/my/mod/v2/mypkg是不同的包,且可能會在一次構(gòu)建中同時引用。

因有些模塊還未轉(zhuǎn)換為Module方式,過度期,會支持如下幾個例外:

  • a)gopkg.in
  • 會繼續(xù)支持gopkg.in/yaml.v1或gopkg.in/yaml.v2等引用方式。
  • b)當(dāng)引用還未Module化的v2+版本包時,會有'+incompatible'后綴。
  • c)當(dāng)Module模式未開啟時,采用最小模塊兼容性。

即在Go 1.11鄰近版本,不開啟Module模式時(GO111MODULE=off),引用v2或以上版本,不會將版本加入路徑中。

3 使用

3.1 模塊支持激活

安裝Go 1.11及以上版本,然后可以使用如下兩種方式中的任一種激活模塊支持。

  • a)在$GOPATH/src文件夾之外使用go命令,且當(dāng)前文件夾或其上層文件夾包含go.mod文件,而GO111MODULE環(huán)境變量未設(shè)置或設(shè)置為了auto;
  • b)設(shè)置GO111MODULE=on,然后調(diào)用go命令。

即在$GOPATH/src之外使用模塊支持,無需設(shè)置GO111MODULE環(huán)境變量,而在$GOPATH/src使用模塊支持,需將GO111MODULE設(shè)置為on。

3.2 定義一個模塊

a)進(jìn)入對應(yīng)文件夾

$ cd path

該文件夾可以為設(shè)置GO111MODULE=on的$GOPATH/src,或該文件夾之外的任意路徑。

b)執(zhí)行g(shù)o mod init

$ go mod init github.com/my/repo

若在初始化一個v2+的模塊,需要手動更改go.mod文件及.go代碼,以在引用路徑及模塊路徑加入版本信息(語義學(xué)版本引用)。

c)構(gòu)建模塊

$ go build ./...

“./...”模式匹配了當(dāng)前模塊下的所有包,go build將自動增加缺失的包。

d)測試模塊

$ go test ./...

或者執(zhí)行如下語句,可以運行模塊內(nèi)的測試及所有直接及間接依賴測試以檢查不兼容問題。

$ go test all

3.3 依賴升降級

可以使用go get命令進(jìn)行日常依賴升級及降級,其會自動更新go.mod文件,當(dāng)然您也可以手動編輯go.mod文件。

當(dāng)然,go get也如go build,go test一樣,會自動加入缺失的依賴包。

查看可用的小版本或補丁更新,可以執(zhí)行:

$ go list -u -m all

將直接或間接依賴更新為最新的小版本或補丁版本,可以執(zhí)行:

$ go get -u

僅更新為補丁版本,可以執(zhí)行:

$ go get -u=patch

go get foo等同于go get foo@latest,會將foo更新為最新版本。

當(dāng)有語義學(xué)版本時,最新版本為語義學(xué)最新版本,沒有時,為最新的提交。

一個通常錯誤的認(rèn)為是,go get -u foo僅獲取最新版本的foo。其實其還會獲取foo的直接或間接依賴的最新版本。

更新版本,推薦的做法是先運行g(shù)o get foo,好使時再運行g(shù)o get -u foo。

進(jìn)行版本升降級時,可以使用@version后綴,如:

$ go get [email protected]

$ go get foo@e3702bed2

還支持模塊查詢,如:

$ go get foo@'<v1.6.2'

使用分支名稱,可以不考慮其是否有語義學(xué)版本,而更新為最新的分支提交。

$ go get foo@master

版本升降級后,需測試是否有不兼容問題:

$ go test all

3.4 模塊版本發(fā)布

發(fā)布前執(zhí)行如下命令,以刪減未使用的包。

go mod tidy

然后執(zhí)行如下命令,保證兼容性。

go test all

然后發(fā)布時,需將go.sum文件與go.mod一起提交。

發(fā)布v2及以上版本時需注意滿足語義學(xué)版本引用規(guī)則,版本需包含在模塊路徑及引用路徑中。創(chuàng)建一個v2及以上的版本,有如下兩種方式:

a)不創(chuàng)建子文件夾

go.mod文件包含vN路徑(如:module github.com/my/module/v3),模塊內(nèi)的包引用亦需修改為包含版本的格式(如:import "github.com/my/module/v3/mypkg")。

b)創(chuàng)建子文件夾

創(chuàng)建vN子文件夾,且將go.mod放至該文件夾下,模塊路徑需以/vN結(jié)尾,然后將代碼拷貝至vN子文件夾下,然后更新模塊內(nèi)的包引用路徑(如:import "github.com/my/module/v3/mypkg")。

最后,創(chuàng)建一個滿足語義學(xué)版本的tag,推送至倉庫即可。

但需注意子模塊的情形,該種情形tag需包含前綴。

如,我們有模塊example.com/repo/sub/v2,然后想發(fā)布版本v2.1.6,倉庫為example.com/repo,子模塊定義在sub/v2/go.mod,提交時tag需命名為sub/v2.1.6。

參考資料

[1] https://github.com/golang/go/wiki/Modules

[2] https://research.swtch.com/vgo

原文鏈接:https://leileiluoluo.com/posts/golang-modules.html

本文作者:磊磊落落的博客

分享到:
標(biāo)簽:Module
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達(dá)人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定