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

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

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

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

 

1 速覽

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

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

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

然后初始化一個(gè)新的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

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

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

hello.go
README.md

現(xiàn)在給依賴工程打一個(gè)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ù)需要加入包引入語(yǔ)句;
  • b)標(biāo)準(zhǔn)命令,如go build及go test等會(huì)自動(dòng)更新go.mod并下載依賴包;
  • c)當(dāng)需要特定版本時(shí),可以使用諸如go get foo@v1.2.3,go get foo@master,go get foo@e3702bed2命令或直接編輯go.mod文件。

其它通用命令:

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

2 概念

2.1 模塊

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

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

通常,一個(gè)版本控制倉(cāng)庫(kù)僅包含一個(gè)Module(支持單倉(cāng)庫(kù)多Module,但其會(huì)比單倉(cāng)庫(kù)單Module復(fù)雜很多)。

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

  • a)一個(gè)倉(cāng)庫(kù)包含一個(gè)或多個(gè)模塊;
  • b)一個(gè)模塊包含一個(gè)或多個(gè)包;
  • c)一個(gè)包在一個(gè)文件夾包含一個(gè)或多個(gè).go文件。

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

模塊由一組源文件樹(shù)在根目錄定義一個(gè)go.mod文件,模塊源碼可以位于GOPATH之外,有如下原語(yǔ)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
)

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

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

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

2.2 版本選擇

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

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

下面舉個(gè)例子:

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

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

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

go list -m all

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

Go多年來(lái)推薦的包版本化方式:

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

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

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

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

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

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

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

  • a)語(yǔ)義學(xué)版本命名;
  • b)若一個(gè)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,模塊路徑及引用路徑無(wú)須包含主版本。

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

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

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

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

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之外使用模塊支持,無(wú)需設(shè)置GO111MODULE環(huán)境變量,而在$GOPATH/src使用模塊支持,需將GO111MODULE設(shè)置為on。

3.2 定義一個(gè)模塊

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

$ cd path

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

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

$ go mod init github.com/my/repo

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

c)構(gòu)建模塊

$ go build ./...

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

d)測(cè)試模塊

$ go test ./...

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

$ go test all

3.3 依賴升降級(jí)

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

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

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

$ go list -u -m all

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

$ go get -u

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

$ go get -u=patch

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

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

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

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

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

$ go get foo@v1.6.2

$ go get foo@e3702bed2

還支持模塊查詢,如:

$ go get foo@'<v1.6.2'

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

$ go get foo@master

版本升降級(jí)后,需測(cè)試是否有不兼容問(wèn)題:

$ go test all

3.4 模塊版本發(fā)布

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

go mod tidy

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

go test all

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

發(fā)布v2及以上版本時(shí)需注意滿足語(yǔ)義學(xué)版本引用規(guī)則,版本需包含在模塊路徑及引用路徑中。創(chuàng)建一個(gè)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)建一個(gè)滿足語(yǔ)義學(xué)版本的tag,推送至倉(cāng)庫(kù)即可。

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

如,我們有模塊example.com/repo/sub/v2,然后想發(fā)布版本v2.1.6,倉(cāng)庫(kù)為example.com/repo,子模塊定義在sub/v2/go.mod,提交時(shí)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ú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

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

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

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

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

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

答題星2018-06-03

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

全階人生考試2018-06-03

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

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

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

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

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

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定