go與go mod命令使用方式以及遇到的問(wèn)題
go包版本更新引起的一些問(wèn)題
在使用go mod tidy或者go run命令時(shí),通常會(huì)下載最新版本的golang的依賴(lài)包,但是有些包更新后,與之前的版本不兼容,如函數(shù)方法傳參、返回類(lèi)型、參數(shù)數(shù)目等都可能發(fā)生變化,這樣就會(huì)經(jīng)常出現(xiàn)之前能夠正常運(yùn)行的程序,在無(wú)意中引入新版本的golang包后,出現(xiàn)一些莫名的異常,下面就記錄幾個(gè)遇到的這方面的問(wèn)題,并給出排查問(wèn)題的經(jīng)過(guò),及解決問(wèn)題,以給遇到相似問(wèn)題的同學(xué)們一些參考。
jwt和iris版本更新問(wèn)題
在使用golang iris框架進(jìn)行后端開(kāi)發(fā)時(shí),使用go run命令運(yùn)行程序,出現(xiàn)

通過(guò)golangci-lint run命令,檢查代碼格式,出現(xiàn):
cannot load github.com/klauspost/compress/snappy: module github.com/klauspost/compress@latest found .......
原因:
在使用go mod tidy或者go run的時(shí)候,默認(rèn)會(huì)下載安裝最新版本的包。
在go.mod文件中,發(fā)現(xiàn)使用的iris是最新的v12.2.0-alpha2測(cè)試版,而這個(gè)版本的好多東西相比v12.1.8版本,函數(shù)的參數(shù),返回值發(fā)生了變化,引起其他包也可能出錯(cuò)。
module github.com/xxxxxx/huoxing go 1.13 require ( github.com/Joker/jade v1.0.0 // indirect github.com/Masterminds/squirrel v1.5.0 github.com/Shopify/goreferrer v0.0.0-20210407190730-c9ba3cb61340 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.1117 github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible github.com/andybalholm/brotli v1.0.3 // indirect github.com/astaxie/beego v1.12.3 github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 // indirect github.com/flosch/pongo2/v4 v4.0.2 // indirect github.com/fsnotify/fsnotify v1.4.9 github.com/gavv/monotime v0.0.0-20190418164738-30dba4353424 // indirect github.com/golang/snappy v0.0.3 // indirect github.com/google/uuid v1.2.0 // indirect github.com/gorilla/schema v1.2.0 // indirect github.com/guregu/null v4.0.0+incompatible github.com/iris-contrib/formBinder v5.0.0+incompatible // indirect github.com/iris-contrib/go.uuid v2.0.0+incompatible github.com/iris-contrib/httpexpect v1.1.2 // indirect github.com/iris-contrib/middleware/jwt v0.0.0-20210110101738-6d0a4d799b5d github.com/jinzhu/gorm v1.9.16 github.com/json-iterator/go v1.1.11 // indirect github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect github.com/kataras/golog v0.1.7 // indirect github.com/kataras/iris v11.1.1+incompatible // indirect github.com/kataras/iris/v12 v12.2.0-alpha2 github.com/mailru/easyjson v0.7.7 // indirect github.com/microcosm-cc/bluemonday v1.0.9 // indirect github.com/pkg/errors v0.9.1 github.com/satori/go.uuid v1.2.0 github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.8.1 github.com/spf13/viper v1.7.1 github.com/tdewolff/minify/v2 v2.9.17 // indirect github.com/tdewolff/parse/v2 v2.5.16 // indirect github.com/valyala/fasthttp v1.11.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect github.com/yudai/pp v2.0.1+incompatible // indirect golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect google.golang.org/protobuf v1.26.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect )
在go.mod最后,添加如下幾行代碼,將響應(yīng)的包替換為指定的版本即可。
replace ( github.com/iris-contrib/middleware/jwt => github.com/iris-contrib/middleware/jwt v0.0.0-20191219204441-78279b78a367 github.com/kataras/iris/v12 => github.com/kataras/iris/v12 v12.1.8 )
最后的go.mod內(nèi)容如下:
module github.com/xxxxxx/huoxing go 1.13 require ( github.com/Joker/jade v1.0.0 // indirect github.com/Masterminds/squirrel v1.5.0 github.com/Shopify/goreferrer v0.0.0-20210407190730-c9ba3cb61340 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.1117 github.com/apache/thrift/lib/go/thrift v0.0.0-20210120171102-e27e82c46ba4 // indirect github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible github.com/andybalholm/brotli v1.0.3 // indirect github.com/astaxie/beego v1.12.3 github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 // indirect github.com/flosch/pongo2/v4 v4.0.2 // indirect github.com/fsnotify/fsnotify v1.4.9 github.com/gavv/monotime v0.0.0-20190418164738-30dba4353424 // indirect github.com/golang/snappy v0.0.3 // indirect github.com/google/uuid v1.2.0 // indirect github.com/gorilla/schema v1.2.0 // indirect github.com/guregu/null v4.0.0+incompatible github.com/iris-contrib/formBinder v5.0.0+incompatible // indirect github.com/iris-contrib/go.uuid v2.0.0+incompatible github.com/iris-contrib/httpexpect v1.1.2 // indirect github.com/iris-contrib/middleware/jwt v0.0.0-20210110101738-6d0a4d799b5d github.com/jinzhu/gorm v1.9.16 github.com/json-iterator/go v1.1.11 // indirect github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect github.com/kataras/golog v0.1.7 // indirect github.com/kataras/iris v11.1.1+incompatible // indirect github.com/kataras/iris/v12 v12.2.0-alpha2 github.com/mailru/easyjson v0.7.7 // indirect github.com/microcosm-cc/bluemonday v1.0.9 // indirect github.com/pkg/errors v0.9.1 github.com/satori/go.uuid v1.2.0 github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.8.1 github.com/spf13/viper v1.7.1 github.com/tdewolff/minify/v2 v2.9.17 // indirect github.com/tdewolff/parse/v2 v2.5.16 // indirect github.com/valyala/fasthttp v1.11.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect github.com/yudai/pp v2.0.1+incompatible // indirect golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect google.golang.org/protobuf v1.26.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) replace ( github.com/iris-contrib/middleware/jwt => github.com/iris-contrib/middleware/jwt v0.0.0-20191219204441-78279b78a367 github.com/kataras/iris/v12 => github.com/kataras/iris/v12 v12.1.8 )
impala和thrift版本更新問(wèn)題
2021.06.07問(wèn)題更新與解決記錄。
執(zhí)行完go mod tidy后,發(fā)現(xiàn)之前正常使用的impala報(bào)錯(cuò):
github.com/bippio/go-impala/services/cli_service
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:721:37: not enough arguments in call to iprot.ReadStructBegin
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:727:57: not enough arguments in call to iprot.ReadFieldBegin
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:739:29: not enough arguments in call to iprot.Skip
have (thrift.TType)
want (context.Context, thrift.TType)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:758:33: not enough arguments in call to iprot.ReadFieldEnd
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:762:32: not enough arguments in call to iprot.ReadStructEnd
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:769:29: not enough arguments in call to iprot.ReadI32
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:778:32: not enough arguments in call to iprot.ReadString
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:790:35: not enough arguments in call to oprot.WriteStructBegin
have (string)
want (context.Context, string)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:796:33: not enough arguments in call to oprot.WriteFieldStop
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:798:33: not enough arguments in call to oprot.WriteStructEnd
have ()
want (context.Context)
..\..\..\..\pkg\mod\github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go:798:33: too many errors
點(diǎn)擊去github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go的第798行,是一個(gè)無(wú)參數(shù)的WriteStructEnd方法:

而再點(diǎn)進(jìn)去WriteStructEnd方法,跳轉(zhuǎn)到thift的TProtocol接口定義,發(fā)現(xiàn)該方法是帶context.Context參數(shù)的,由此推斷應(yīng)該是thift版本升級(jí)或者應(yīng)用的包不當(dāng),造成與go-impala的版本不一致,使得impala中使用的函數(shù)參數(shù)及返回值發(fā)生改變,而導(dǎo)致異常。

將go.mod文件中require中的 github.com/apache/thrift/lib/go/thrift v0.0.0-20210120171102-e27e82c46ba4 // indirect 改為 github.com/apache/thrift v0.13.0 // indirect并將go-impala v2.1.0版本指定為v2.0.0版本,重新go mod tidy即可。
require ( ...... github.com/apache/thrift v0.13.0 // indirect ...... ) replace ( ...... github.com/bippio/go-impala => github.com/bippio/go-impala v2.0.0+incompatible ...... )
go mod使用
go mod是什么
go.mod是自golang1.11版本新引入的官方包管理工具,它主要用于解決之前沒(méi)有地方記錄依賴(lài)包具體版本的問(wèn)題,相比vendor、dep等包管理工具,更加便于依賴(lài)包的管理。
go.mod其實(shí)就是一個(gè)modules,關(guān)于modules的官方定義為:
modules是相關(guān)go包的集合,是源代碼交換和版本控制的單元。
go命令直接支持使用modules,包括記錄和解析對(duì)其他模塊的依賴(lài)性。modules替換golang舊版本中基于GOPATH的方式,來(lái)指定使用哪些源文件。
modules和傳統(tǒng)的GOPATH不同,不需要包含例如src,bin這樣的子目錄,一個(gè)源代碼目錄甚至是空目錄都可以作為modules,只要其中包含有g(shù)o.mod文件。
如何使用go.mod
1.首先將go的版本升級(jí)為1.11及以上
2.設(shè)置GO111MODULE
GO111MODULE有三個(gè)值:off, on和auto(默認(rèn)值)。
- GO111MODULE=off,go命令行將不會(huì)支持module功能,尋找依賴(lài)包的方式將會(huì)沿用舊版本那種通過(guò)vendor目錄或者GOPATH模式來(lái)查找。
- GO111MODULE=on,go命令行會(huì)使用modules,不會(huì)去GOPATH目錄下查找。
- GO111MODULE=auto,默認(rèn)值,使用該方式時(shí),go命令行將會(huì)根據(jù)當(dāng)前目錄來(lái)決定是否啟用module功能。
包的版本控制
在使用go build、go test、go list、go tidy等命令時(shí),go會(huì)自動(dòng)更新go.mod文件,將項(xiàng)目依賴(lài)的包、包版本等依賴(lài)關(guān)系寫(xiě)入該文件。
使用mod進(jìn)行包管理的另外一項(xiàng)重要功能就是包的版本控制。go.mod文件中的依賴(lài)內(nèi)容,如下:
require ( github.com/Shopify/goreferrer v0.0.0-20210407190730-c9ba3cb61340 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.1117 github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible github.com/andybalholm/brotli v1.0.3 // indirect github.com/astaxie/beego v1.12.3 )
go.mod require括號(hào)里面的前面部分是包的名字,也就是項(xiàng)目package包中import時(shí)需要導(dǎo)入的依賴(lài)部分,而空格之后的是版本號(hào),版本號(hào)遵循如下規(guī)律:
vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef vX.0.0-yyyymmddhhmmss-abcdefabcdef vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef vX.Y.Z
也就是:版本號(hào)-時(shí)間戳-hash,當(dāng)自己想要使用具體的版本時(shí)只需要指定版本號(hào)即可,沒(méi)有版本tag的則需要找到對(duì)應(yīng)commit的時(shí)間和hash值。而默認(rèn)使用的是最新版本的package。
當(dāng)前最新的iris版本為v12.2.0-alpha2,如果想使用v12.1.8版本的iris,需要怎么辦呢?
只需要如下命令:
go mod edit -require="github.com/kataras/iris/v12@v12.1.8"
但是,這種方式,在下一次使用go tidy更新依賴(lài)關(guān)系的時(shí)候,又會(huì)更新成最新版本的iris,那么需要怎么辦呢?
這就需要配合replace命令,將特定包替換為指定的版本號(hào),參看下面小節(jié)"在go-mod中指定包的版本號(hào)"。
在go-mod中指定包的版本號(hào)
在go.mod中,使用replace指定包版本號(hào)。比如將google.golang.org/grpc最新版本替換為指定的v1.26.0,可以在go.mod的最后面,添加如下信息:
replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
然后,再運(yùn)行g(shù)o run或go build即可。
go mod常用命令
go.mod 提供了module、require、replace和exclude 四種管理包及依賴(lài)的方式。
- module 語(yǔ)句,表示指定包的名字(項(xiàng)目路徑)
- require 語(yǔ)句,表示項(xiàng)目指定的依賴(lài)項(xiàng)模塊
- replace 語(yǔ)句,表示可以替換的依賴(lài)項(xiàng)模塊
- exclude 語(yǔ)句,表示可以忽略依賴(lài)項(xiàng)模塊
使用go mod管理go包時(shí),主要有以下一些命令:

其中,最常使用的命令有g(shù)o init、go tidy等。
$go mod init 項(xiàng)目路徑 go mod init初始化go.mod文件,go.mod文件一旦創(chuàng)建后,它的內(nèi)容將會(huì)被go toolchain全面掌控。go toolchain會(huì)在各類(lèi)命令執(zhí)行時(shí),比如go get、go build、go mod等修改和維護(hù)go.mod文件。 $go mod tidy go mod tidy 命令,刪除go.mod中不需要的依賴(lài)、新增需要的依賴(lài)。使用該命令,項(xiàng)目中需要的依賴(lài)會(huì)自動(dòng)生成 require 語(yǔ)句
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Go-RESTful實(shí)現(xiàn)下載功能思路詳解
這篇文章主要介紹了Go-RESTful實(shí)現(xiàn)下載功能,文件下載包括文件系統(tǒng)IO和網(wǎng)絡(luò)IO,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10
Go語(yǔ)言Web編程實(shí)現(xiàn)Get和Post請(qǐng)求發(fā)送與解析的方法詳解
這篇文章主要介紹了Go語(yǔ)言Web編程實(shí)現(xiàn)Get和Post請(qǐng)求發(fā)送與解析的方法,結(jié)合實(shí)例形式分析了Go語(yǔ)言客戶(hù)端、服務(wù)器端結(jié)合實(shí)現(xiàn)web數(shù)據(jù)get、post發(fā)送與接收數(shù)據(jù)的相關(guān)操作技巧,需要的朋友可以參考下2017-06-06
通過(guò)Golang實(shí)現(xiàn)無(wú)頭瀏覽器截圖
在Web開(kāi)發(fā)中,有時(shí)需要對(duì)網(wǎng)頁(yè)進(jìn)行截圖,以便進(jìn)行頁(yè)面預(yù)覽、測(cè)試等操作,本文為大家整理了Golang實(shí)現(xiàn)無(wú)頭瀏覽器的截圖的方法,感興趣的可以了解一下2023-05-05
利用rpm打包上線(xiàn)部署golang代碼的方法教程
RPM是RPM Package Manager(RPM軟件包管理器)的縮寫(xiě),這篇文章主要給大家介紹了關(guān)于利用rpm打包上線(xiàn)部署golang代碼的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01
詳解Go語(yǔ)言strconv與其他基本數(shù)據(jù)類(lèi)型轉(zhuǎn)換函數(shù)的使用
這篇文章將以 string 類(lèi)型為中心,通過(guò) strconv 標(biāo)準(zhǔn)庫(kù),介紹其與其他基本數(shù)據(jù)類(lèi)型相互轉(zhuǎn)換的函數(shù)。文中的示例代碼講解詳細(xì),感興趣的可以了解一下2022-12-12
Go 語(yǔ)言 JSON 標(biāo)準(zhǔn)庫(kù)的使用
今天通過(guò)本文給大家介紹Go 語(yǔ)言 JSON 標(biāo)準(zhǔn)庫(kù)的使用小結(jié),包括序列化和反序列化的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧2021-10-10
golang xorm及time.Time自定義解決json日期格式的問(wèn)題
這篇文章主要介紹了golang xorm及time.Time自定義解決json日期格式的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12

