日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

正在或即将被使用的Go依赖包管理方法:Go Modules,Go 1.13的标准特性

發(fā)布時(shí)間:2025/4/14 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 正在或即将被使用的Go依赖包管理方法:Go Modules,Go 1.13的标准特性 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

公眾號(hào)原文地址:https://mp.weixin.qq.com/s/SGGV3tWEg5AAJ7I_FcK0cg

目錄

  • 目錄

  • 說(shuō)明

  • 初始化

  • 依賴(lài)包的默認(rèn)導(dǎo)入

  • 依賴(lài)包的特定版本導(dǎo)入

  • 查看已添加依賴(lài)

  • 依賴(lài)包的存放管理

  • 依賴(lài)包的版本切換

  • 刪除未使用依賴(lài)包

  • 引用項(xiàng)目中的 package

  • 引用不同版本的父子目錄

  • 實(shí)例演示

  • 需要注意的坑

  • IDE 與 Go Modules

  • IntelliJ IDEA/Goland

  • vim

  • 參考

說(shuō)明

Go 的依賴(lài)包管理一直是個(gè)問(wèn)題,先后出現(xiàn)了 godep、glide、dep 等一系列工具,vendor 機(jī)制使依賴(lài)包的管理方便了很多,但依然沒(méi)有統(tǒng)一的管理工具,不同的項(xiàng)目各用各的方法。

另外使用 vendor 后,每個(gè)項(xiàng)目都完整拷貝一份依賴(lài)包,既不方便管理又浪費(fèi)了本地空間。

此外,Go 項(xiàng)目中的 import 指令后面的 package 路徑與項(xiàng)目代碼的存放路徑相關(guān),項(xiàng)目目錄不能隨意移動(dòng),必須安分守己地趴在 $GOPATH/src 中,否則 import 會(huì)找不到項(xiàng)目中的 package,雖然可以通過(guò)在容器中編譯或者為每個(gè)項(xiàng)目準(zhǔn)備一套 Go 環(huán)境的方式解決,但是麻煩且有額外開(kāi)銷(xiāo)。

Go1.11 和 Go1.12 引入的 Go Modules 機(jī)制,提供了統(tǒng)一的依賴(lài)包管理工具 go mod,依賴(lài)包統(tǒng)一收集在 $GOPATH/pkg/mod 中進(jìn)行集中管理,并且將 import 路徑與項(xiàng)目代碼的實(shí)際存放路徑解耦,使 package 定義導(dǎo)入更加靈活。

Go Modules 將成為 Go1.13 默認(rèn)的依賴(lài)包管理方法,在 Go1.11 和 Go1.12 中, Go Modules 只能在 $GOPATH 外部使用,Using Go Modules 中有詳細(xì)介紹。

很多開(kāi)源項(xiàng)目已經(jīng)改用 Go Modules 了,瀏覽代碼的時(shí)候會(huì)發(fā)現(xiàn),很多項(xiàng)目的 master 分支中增加了 go.mod 和 go.sum 文件。

Go Modules 的主要功能就四個(gè):添加依賴(lài)、更新依賴(lài)、刪除依賴(lài),以及多版本依賴(lài)。

初始化

Go Modules 的初始化命令為?go mod init <ROOTPATH>,ROOTPATH 是項(xiàng)目的 import 路徑。

在 $GOPATH 外部創(chuàng)建一個(gè)目錄,然后初始化,項(xiàng)目的路徑設(shè)置為?exampe.com/hello:

$ mkdir go-modules-example$ cd go-modules-example$ go mod init example.com/hello # 該項(xiàng)目代碼的引用路徑是 example.com/hellogo: creating new go.mod: module example.com/hello

引用該項(xiàng)目中的 package 時(shí)使用前綴?example.com/hello。

項(xiàng)目下生成一個(gè) go.mod 文件,里面記錄了 module 路徑和 go 的版本,剛創(chuàng)建時(shí)這個(gè)文件中沒(méi)有依賴(lài)信息:

$ cat go.modmodule example.com/hellogo 1.12

對(duì)于 Go1.11 和 Go1.12,如果在 $GOPATH 中執(zhí)行 go mod 會(huì)遇到下面的錯(cuò)誤:

$ go mod init example.com/hellogo: modules disabled inside GOPATH/src by GO111MODULE=auto; see 'go help modules'

依賴(lài)包的默認(rèn)導(dǎo)入

在 go-modules-example 中創(chuàng)建一個(gè) main.go,簡(jiǎn)單寫(xiě)幾行代碼,引入 “github.com/lijiaocn/golib/version”:

// Create: 2019/05/05 16:53:00 Change: 2019/05/05 16:56:53// FileName: main.go// Copyright (C) 2019 lijiaocn <lijiaocn@foxmail.com>//// Distributed under terms of the GPL license.package mainimport ( "github.com/lijiaocn/golib/version")func main() { version.Show()}

用下面的 Makefile 編譯( Makefile 純粹為了方便,直接用 go build 也可以):

# Makefile# lijiaocn, 2019-05-05 16:56#VERSION=1.0.0COMPILE=$(shell date -u "+%Y-%m-%d/%H:%M:%S")all: buildbuild: go build -ldflags "-X github.com/lijiaocn/golib/version.VERSION=${VERSION} -X github.com/lijiaocn/golib/version.COMPILE=${COMPILE}"

編譯或者用 go test 運(yùn)行測(cè)試代碼時(shí),默認(rèn)將 import 引入的 package 的最新版本寫(xiě)入 go.mod 和 go.sum:

$ makego build -ldflags "-X github.com/lijiaocn/golib/version.VERSION=1.0.0 -X github.com/lijiaocn/golib/version.COMPILE=2019-05-05/09:55:04"go: finding github.com/lijiaocn/golib v0.0.1go: downloading github.com/lijiaocn/golib v0.0.1go: extracting github.com/lijiaocn/golib v0.0.1

go.mod 中寫(xiě)入依賴(lài)關(guān)系:

$ cat go.modmodule example.com/hellogo 1.12require github.com/lijiaocn/golib v0.0.1

go.sum 中記錄的完整依賴(lài):

$ cat go.sumgithub.com/lijiaocn/golib v0.0.1 h1:bC8xWHei7xTa8x65ShiPBNjVYXoxt6EDmnSUaGgRUW8=github.com/lijiaocn/golib v0.0.1/go.mod h1:BUO0RF2eDlol519GuXLQtlku8pdUim0h+f6wvX/AsNk=

依賴(lài)包的特定版本導(dǎo)入

在使用 go modules 的項(xiàng)目目錄中,用 go get 下載的代碼包自動(dòng)作為依賴(lài)包添加,例如:

$ go get github.com/lijiaocn/codes-go/01-02-hellogo: finding github.com/lijiaocn/codes-go/01-02-hello latestgo: finding github.com/lijiaocn/codes-go latestgo: downloading github.com/lijiaocn/codes-go v0.0.0-20180220071929-9290fe35de7ego: extracting github.com/lijiaocn/codes-go v0.0.0-20180220071929-9290fe35de7e

go.mod 中增加了一行記錄,新增的依賴(lài)被標(biāo)注為?indirect,意思是還沒(méi)有被使用:

$ cat go.modmodule example.com/hellogo 1.12require ( github.com/lijiaocn/codes-go v0.0.0-20180220071929-9290fe35de7e // indirect github.com/lijiaocn/golib v0.0.1)

在用 go get 添加依賴(lài)的時(shí)候,可以用?@v1.1?樣式的后綴指定依賴(lài)的版本,例如:

$ go get github.com/lijiaocn/glib@v0.0.2

查看已添加依賴(lài)

go list?命令列出當(dāng)前項(xiàng)目的依賴(lài)包以及代碼版本:

$ go list -m allexample.com/hellogithub.com/lijiaocn/codes-go v0.0.0-20180220071929-9290fe35de7egithub.com/lijiaocn/golib v0.0.1

依賴(lài)包的存放管理

依賴(lài)包既不在?GOPATH/pkg/mod` 目錄中:

$ ls $GOPATH/pkg/mod/github.com/lijiaocn/codes-go@v0.0.0-20180220071929-9290fe35de7e golib@v0.0.1$ ls $GOPATH/pkg/mod/github.com/lijiaocn/golib@v0.0.1config container generator terminal version virtio

如上所示,目錄名中包含版本信息,例如 golib@v0.0.1。

$GOPATH/pkg/mod/cache/download/?中有原始代碼的緩存,避免重復(fù)下載:

$ ls $GOPATH/pkg/mod/cache/download/github.com/lijiaocncodes-go golib$ ls $GOPATH/pkg/mod/cache/download/github.com/lijiaocn/golib/@vlist list.lock v0.0.1.info v0.0.1.lock v0.0.1.mod v0.0.1.zip v0.0.1.ziphash

依賴(lài)包的版本切換

依賴(lài)代碼的版本更新很簡(jiǎn)單,直接用 go get 獲取指定版本的依賴(lài)代碼即可,例如將 lijiaocn/glib 更新到 v0.0.2:

$ go get github.com/lijiaocn/glib@v0.0.2go: finding github.com/lijiaocn/golib v0.0.2go: downloading github.com/lijiaocn/golib v0.0.2go: extracting github.com/lijiaocn/golib v0.0.2

可以看到依賴(lài)的代碼版本發(fā)生了變化:

$ go list -m allexample.com/hellogithub.com/lijiaocn/codes-go v0.0.0-20180220071929-9290fe35de7egithub.com/lijiaocn/golib v0.0.2

刪除未使用依賴(lài)

不需要的依賴(lài)必須手動(dòng)清除,執(zhí)行?go mod tidy,清除所有未使用的依賴(lài):

$ go mod tidy $ go list -m allexample.com/hellogithub.com/lijiaocn/golib v0.0.2

引用項(xiàng)目中的 package

在項(xiàng)目中創(chuàng)建一個(gè)名為 display 的 package:

$ tree displaydisplay└── display.go

導(dǎo)入時(shí)使用 go mod 初始化時(shí)定義的前綴,example.com/hello/display:

import ( "example.com/hello/display" "github.com/lijiaocn/golib/version" )

引用當(dāng)前項(xiàng)目中的 package 時(shí),import 使用的路徑和項(xiàng)目所在的路徑徹底解耦,但是要注意,如果提供給外部項(xiàng)目使用,需要確保 go get 能夠從 example.com 獲得 /hello/display。

引用不同版本的父子目錄

Using Go Modules 中有一節(jié)是?Adding a dependency on a new major version,示例中引入了 v1.5.2 版本的 rsc.io/quote,和 v3.1.0 版本的 rsc.io/quote/v3,這兩個(gè) package 是父子目錄,版本不相同:

package helloimport ( "rsc.io/quote" quoteV3 "rsc.io/quote/v3")func Hello() string { return quote.Hello()}func Proverb() string { return quoteV3.Concurrency()} ? rsc.io tree quotequote├── LICENSE├── README.md├── buggy│ └── buggy_test.go├── go.mod├── go.sum├── quote.go├── quote_test.go└── v3 ├── go.mod ├── go.sum └── quote.go2 directories, 10 files

注意,v3 是一個(gè)真實(shí)存在的子目錄,必須是用 go modules 管理的,rsc.io/quote 和 rsc.io/quote/v3 是父子目錄,但它們是完全獨(dú)立的 package。

引用 1.5.2 版本的 rsc.io/quote 和 v3.1.0 版本的 rsc.io/quote/v3 :

$ go get rsc.io/quote@v1.5.2 ...$ go get rsc.io/quote/v3@v3.1.0 ...

可以看到兩個(gè)版本同時(shí)存在:

$ go list -m rsc.io/q...rsc.io/quote v1.5.2rsc.io/quote/v3 v3.1.0

實(shí)例演示

實(shí)現(xiàn)一個(gè)用 go modules 管理的 package: github.com/introclass/go_mod_example_pkg

image

在另一個(gè)使用 go modules 的項(xiàng)目中引用 v1.0.1 版本:github.com/introclass/go-mod-example

$ go get github.com/introclass/go_mod_example_pkg@v1.0.1go: finding github.com/introclass/go_mod_example_pkg v1.0.1go: downloading github.com/introclass/go_mod_example_pkg v1.0.1go: extracting github.com/introclass/go_mod_example_pkg v1.0.1

查看依賴(lài)的代碼,顯示依賴(lài)的是 v1.0.1:

$ go list -m allexample.com/hellogithub.com/introclass/go_mod_example_pkg v1.0.1github.com/lijiaocn/golib v2.0.1+incompatible

在 main 函數(shù)中使用導(dǎo)入的依賴(lài)包:

package mainimport ( "example.com/hello/display" pkg "github.com/introclass/go_mod_example_pkg" "github.com/lijiaocn/golib/version")func main() { version.Show() display.Display("display print\n") pkg.Vesrion()}

編譯執(zhí)行,輸出的v1.0.1:

$ ./helloversion: compile at: golib v2display printv1.0.1

將依賴(lài)包切換到版本 2.0.1:

$ go get github.com/introclass/go_mod_example_pkg@v2.0.1go: finding github.com/introclass/go_mod_example_pkg v2.0.1

重新編譯執(zhí)行,輸出的版本是 v2.0.1:

$ ./helloversion: compile at: golib v2display printv2.0.1

引用依賴(lài)包 v3.0.1 版本的 v3 子目錄(事實(shí)上是一個(gè)獨(dú)立的 pacakge ):

$ go get github.com/introclass/go_mod_example_pkg/v3@v3.0.1go: finding github.com/introclass/go_mod_example_pkg/v3 v3.0.1go: downloading github.com/introclass/go_mod_example_pkg/v3 v3.0.1go: extracting github.com/introclass/go_mod_example_pkg/v3 v3.0.1

修改 main 函數(shù),引用 v3:

package mainimport ( "example.com/hello/display" pkg "github.com/introclass/go_mod_example_pkg" pkgv3 "github.com/introclass/go_mod_example_pkg/v3" "github.com/lijiaocn/golib/version")func main() { version.Show() display.Display("display print\n") pkg.Vesrion() pkgv3.Vesrion()}

重新編譯執(zhí)行,分別輸出 v2.0.1 和 v3.0.1 in v3:

$ ./helloversion: compile at: golib v2display printv2.0.1v3.0.1 in v3

需要注意的坑

1、引用不同版本的父子目錄,被引用的父子目錄必須是用 go mod 管理的 package,非 go mod 管理的代碼不行;

2、go mod 會(huì)在本地緩存代碼,如果被引用的代碼的版本號(hào)不變,但是代碼變了(在做實(shí)驗(yàn)或者代碼版本管理比較亂的時(shí)候,可能會(huì)出現(xiàn)的這種情況),清除本地緩存(?GOPATH/pkg/mod/ 依賴(lài)代碼 )后,才能重新拉取最新的代碼(可能會(huì)有其它的更新緩存的方法);

3、如果被外部項(xiàng)目引用,go.mod 中設(shè)置的 package 路徑需要與代碼的獲取地址相同,項(xiàng)目?jī)?nèi)部引用沒(méi)有該限制,github.com/introclass/go-mod-example 的 go.mod 中標(biāo)注的是 example.com/hello,代碼獲取地址 github.com/intraoclass/go-mode-example 與 example.com/hello 不一致,在另一個(gè)項(xiàng)目中用 github 地址加載時(shí)會(huì)失敗:

$ go get github.com/introclass/go-mod-examplego: finding github.com/introclass/go-mod-example latestgo: github.com/introclass/go-mod-example@v0.0.0-20190605063729-4a841a8278e3: parsing go.mod: unexpected module path "example.com/hello"go: error loading module requirements

IDE 與 Go Modules 項(xiàng)目

IntelliJ IDEA/Goland

在 IntelliJ IDEA 或者 Goland 中(需要是最新的2019.1版本)導(dǎo)入使用 Go Module 的項(xiàng)目的時(shí)候,要選擇?Go Module(vgo),否則 IDE 找不到 import 導(dǎo)入的代碼,create-a-project-with-vgo-integration 有更多介紹:

image

IntelliJ IDEA/Goland 左側(cè)編碼顯示的依賴(lài)代碼(帶有版本號(hào)或者 commit id):

image

vim

vim插件 vim-go 從 v1.19 開(kāi)始支持 go.mod,但是代碼跳轉(zhuǎn)等還不支持。

cmd/go: track tools/tooling updates to support modules 列出了一些工具對(duì) go module 的支持情況。

參考

  • Using Go Modules

  • Where is the module cache in golang?

  • create-a-project-with-vgo-integration

  • cmd/go: track tools/tooling updates to support modules

  • 上一篇:源代碼閱讀方法(附Go語(yǔ)言項(xiàng)目的代碼閱讀技巧)

    關(guān)注后加作者微信

    image

    公眾號(hào)原文地址:https://mp.weixin.qq.com/s/SGGV3tWEg5AAJ7I_FcK0cg

    轉(zhuǎn)載于:https://www.cnblogs.com/lijiaocn/p/11178642.html

    總結(jié)

    以上是生活随笔為你收集整理的正在或即将被使用的Go依赖包管理方法:Go Modules,Go 1.13的标准特性的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。