重學(xué)Go語言之如何使用Modules
Module
在Go Modules這種新的依賴機(jī)制中定義了Module這個(gè)概念,也就是所謂的模塊。
模塊的組成
一個(gè)模塊就是一個(gè)或者多個(gè)包(package)的集合,創(chuàng)建模塊時(shí),會(huì)在根目錄下生成一個(gè)go.mod文件,go.mod文件包含了模塊的路徑(module path)以及該模塊依賴的其他模塊列表,在下載依賴模塊后,還會(huì)生成一個(gè)go.sum文件,因此大體上,模塊的構(gòu)成如下圖所示:

module path
module path,即模塊路徑,是該模塊的身份標(biāo)識(shí),在模塊內(nèi)或者其他模塊導(dǎo)入該模塊的包時(shí),必須以模塊路徑為前綴,比如模塊路徑為github.com/test/test,那么導(dǎo)入該模塊的hello包時(shí),則其導(dǎo)入的路徑為:
import?"github.com/test/test/hello"
下載依賴模塊時(shí)也需要使用到模塊路徑:
go?get?github.com/test/test
語義化版本號(hào)
同一個(gè)模塊可能會(huì)存在不同的版本,Go模塊采用語義化版本號(hào)來定義模塊的版本,其版本號(hào)格式為:
v<major>.<minor>.<patch>
- major:主版本號(hào),當(dāng)模塊做了不兼容的修改后,需更改主版本號(hào)。
- minor:次版本號(hào),當(dāng)模塊做了向下兼容的功能時(shí),需要更改次版本號(hào)。
- patch:修訂版本號(hào),當(dāng)模塊做了向下兼容的bug修改時(shí),需要更改修訂版本號(hào)。
前面我們使用go get命令下載依賴模塊時(shí)并沒有指定義版本號(hào),那么默認(rèn)下載master分支上最新的commit:
go?get?github.com/test/test
如果指定版本號(hào),且該版本號(hào)有對(duì)應(yīng)的tag,那么就會(huì)下載對(duì)應(yīng)的tag,如果沒有對(duì)應(yīng)tag,那么還是下載master分支上最新的commmit:
go?get?github.com/test/test@v1.1.1
使用@latest可以下載最新版本的模塊:
go?get?github.com/test/test@latest
當(dāng)主版本號(hào)為v0或者v1時(shí),在下載和導(dǎo)入時(shí),可以省略版本號(hào),當(dāng)主版本大于或等于v2時(shí),不可省略主版本號(hào):
比如我們現(xiàn)在要下載有模塊有v1.6.0、v1.7.0以及v2.0.5三個(gè)版本,此時(shí):
go?get?github.com/test/test go?get?github.com/test/test@latest
上面的語句會(huì)下載v1.7.0,這是因?yàn)橹靼姹緑1版本可以省略且未指定版本,其效果與@latest一樣。
因?yàn)?code>1.6.0版本不是v1的最版本,所以要下載v1.6.0版本,則需要指定版本號(hào):
go?get?github.com/test/test@1.6.0
如果要下載v2.0.5版本,下載路徑為:
go?get?github.com/test/test/v2
創(chuàng)建一個(gè)新的模塊
創(chuàng)建模塊的命令為go mod init,該命令后面的參數(shù)就是模塊路徑,在目錄名為hello的空目錄執(zhí)行以下語句:
$?go?mod?init?example.com/hello
此時(shí)在hello目錄會(huì)生成一個(gè)go.mod文件:
module?example.com/hello go?1.20
創(chuàng)建hello.go文件,代碼如下:
package?hello
func?Hello()?string?{
????return?"Hello,?world."
}創(chuàng)建hello_test.go文件,代碼如下:
package?hello
import?"testing"
func?TestHello(t?*testing.T)?{
????want?:=?"Hello,?world."
????if?got?:=?Hello();?got?!=?want?{
????????t.Errorf("Hello()?=?%q,?want?%q",?got,?want)
????}
}運(yùn)行go test命令:
$?go?test PASS ok??????example.com/hello???????0.024s
這樣,我們就已經(jīng)創(chuàng)建了一個(gè)自己的模塊。
依賴其他的模塊
Go Modules的作用就在于定義與規(guī)范了模塊之間的版本依賴關(guān)系,通過這套機(jī)制,我們可以在自己的模塊中導(dǎo)入其他的模塊。
現(xiàn)在我們假設(shè)有一個(gè)其他開發(fā)者創(chuàng)建好的模塊:github.com/test/MyUtil,該模塊當(dāng)前的版本為v1.13,我們使用import語句導(dǎo)出,并在Hello()方法中使用:
package?hello
import?"github.com/test/MyUtil"
func?Hello()?string?{
????return?MyUtil.Hello()
}現(xiàn)在代碼還不能運(yùn)行,因?yàn)槲覀冞€沒將該模塊下載到本地,下載依賴的模塊使用go get命令:
$?go?get?github.com/test/MyUtil go:?downloading?github.com/test/MyUtil?v1.1.3 go:?added?github.com/test/MyUtil?v1.1.3
下載了依賴的模塊之后,go.mod文件會(huì)記錄當(dāng)前模塊的依賴項(xiàng):
module?example.com/hello go?1.20 require?github.com/test/MyUtil?v1.1.3
另外,下載依賴模塊時(shí)也會(huì)生成一個(gè)go.sum文件,其內(nèi)容如下:
github.com/test/MyUtil?v1.1.3?h1:A2x2RDcKl0rxZaOKk0Mn71HQfISoS/0Vex+UHjtou4o= github.com/test/MyUtil?v1.1.3/go.mod?h1:8PqlR4GowL1as1JuS979xEp6TmJjrCIG+Bnjrdo3bfE=
go.sum文件在下載依賴時(shí)會(huì)發(fā)生變化,每個(gè)依賴模塊可能會(huì)生成兩行記錄,一行表示依賴模塊的全體文件的SHA-256哈希值,另一行則為依賴模塊的go.mod文件的哈希值。
再次運(yùn)行go test命令:
$?go?test PASS ok??????example.com/hello???????0.024s
現(xiàn)在,我們就已經(jīng)成功在自己的模塊中調(diào)用其他模塊的功能了。
升級(jí)依賴的模塊
我們依賴的模塊也會(huì)更新升級(jí),現(xiàn)在假設(shè)模塊MyUtil增加了其他函數(shù),并且版本升級(jí)到v.1.12.10,我們可以調(diào)用go get命令模塊版本升級(jí)。
在模塊路徑后面可以指定義升級(jí)的版本:
?go?get?github.com/test/MyUtil@1.12.10
也可以在路徑后直接跟上@latest升級(jí)最新的版本:
github.com/test/MyUtil@latest?
因?yàn)楫?dāng)前最新版本為v1.12.10,因此上面兩種路徑的效果是一樣的:
$?go?get?github.com/test/MyUtil@latest?? go:?downloading?github.com/test/MyUtil?v1.12.10 go:?upgraded?github.com/test/MyUtil?v1.1.3?=>?v1.12.10
從go.mod文件可以看出依賴模塊版本的變化:
module?example.com/hello go?1.20 require?github.com/test/MyUtil?v1.12.10
添加一個(gè)新的主版本
當(dāng)模塊的主版本號(hào)發(fā)生變化時(shí),比如從v1升級(jí)到v2,說明新版本做出之前不兼容的變更,我們可以通過在模塊路徑后面跟上版本來下載對(duì)應(yīng)的版本:
?go?get?github.com/test/MyUtil/v2
此時(shí)import語句后面的路徑也發(fā)生了變化:
package?hello
import?(
?"github.com/test/MyUtil"
?v2?"github.com/test/MyUtil/v2"
)
func?Hello()?string?{
?return?MyUtil.Hello()
}
func?Hello2()?string?{
?return?v2.HelloV2("%s",?"Hello")
}小結(jié)
Go Module是一種比較復(fù)雜的依賴解決方案,今天的這篇文章算是講解了Go Modules的基本使用與一些基本概念,沒有涉及到Go Modules的全部知識(shí),在以后的文章,我們?cè)僭敿?xì)展開。
到此這篇關(guān)于重學(xué)Go語言之如何使用Modules的文章就介紹到這了,更多相關(guān)Go Modules內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Goland使用Go Modules創(chuàng)建/管理項(xiàng)目的操作
- Linux中Go環(huán)境配置和GoModule常用操作
- Go?modules?replace解決Go依賴引用問題
- go modules中replace使用方法
- GoLang中Module的基本使用方法
- go module構(gòu)建項(xiàng)目的實(shí)現(xiàn)
- 詳解golang中?work與?module?的區(qū)別與聯(lián)系
- 淺析Go項(xiàng)目中的依賴包管理與Go?Module常規(guī)操作
- Go Module常用命令及如何使用Go Module
- Go Module依賴管理的實(shí)現(xiàn)
相關(guān)文章
golang結(jié)構(gòu)化日志slog的用法簡介
日志是任何軟件的重要組成部分,Go?提供了一個(gè)內(nèi)置日志包(slog),在本文中,小編將簡單介紹一下slog包的功能以及如何在?Go?應(yīng)用程序中使用它,感興趣的可以了解下2023-09-09
Go使用協(xié)程批量獲取數(shù)據(jù)加快接口返回速度
這篇文章主要介紹了Go使用協(xié)程批量獲取數(shù)據(jù)加快接口返回速度,使用Go語言后,可以并發(fā)獲取,極大提升效率,需要的朋友可以參考下2023-02-02
Go語言實(shí)現(xiàn)一個(gè)Http Server框架(二) Server的抽象
上一篇文章對(duì)http庫的基本使用做了說明,這篇文章主要介紹了如何實(shí)現(xiàn)一個(gè)簡單地httpServer,文中代碼示例非常詳細(xì),感興趣的朋友可以參考下2023-04-04
GO使用socket和channel實(shí)現(xiàn)簡單控制臺(tái)聊天室
今天小編給大家分享一個(gè)簡單的聊天室功能,聊天室主要功能是用戶可以加入離開聊天室,實(shí)現(xiàn)思路也很簡單明了,下面小編給大家?guī)砹送暾a,感興趣的朋友跟隨小編一起看看吧2021-12-12
Golang中List的實(shí)現(xiàn)方法示例詳解
最近決定復(fù)習(xí)下Go,所以下面這篇文章主要給大家介紹了關(guān)于Golang中List的實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09
Golang 統(tǒng)計(jì)字符串字?jǐn)?shù)的方法示例
本篇文章主要介紹了Golang 統(tǒng)計(jì)字符串字?jǐn)?shù)的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05

