go与go mod命令使用及遇到的问题

go与go mod命令使用及遇到的问题,第1张

go包版本更新引起的一些问题

在使用go mod tidy或者go run命令时,通常会下载最新版本的golang的依赖包,但是有些包更新后,与之前的版本不兼容,如函数方法传参、返回类型、参数数目等都可能发生变化,这样就会经常出现之前能够正常运行的程序,在无意中引入新版本的golang包后,出现一些莫名的异常,下面就记录几个遇到的这方面的问题,并给出排查问题的经过,及解决问题,以给遇到相似问题的同学们一些参考。

jwt和iris版本更新问题

在使用golang iris框架进行后端开发时,使用go run命令运行程序,出现

通过golangci-lint run命令,检查代码格式,出现:

cannot load github.com/klauspost/compress/snappy: module github.com/klauspost/compress@latest found .......

原因:在使用go mod tidy或者go run的时候,默认会下载安装最新版本的包。在go.mod文件中,发现使用的iris是最新的v12.2.0-alpha2测试版,而这个版本的好多东西相比v12.1.8版本,函数的参数,返回值发生了变化,引起其他包也可能出错。

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最后,添加如下几行代码,将响应的包替换为指定的版本即可。

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内容如下:

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版本更新问题

2021.06.07问题更新与解决记录。
执行完go mod tidy后,发现之前正常使用的impala报错:

 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

点击去github.com\bippio\go-impala@v2.1.0+incompatible\services\cli_service\cli_service.go的第798行,是一个无参数的WriteStructEnd方法:

而再点进去WriteStructEnd方法,跳转到thift的TProtocol接口定义,发现该方法是带context.Context参数的,由此推断应该是thift版本升级或者应用的包不当,造成与go-impala的版本不一致,使得impala中使用的函数参数及返回值发生改变,而导致异常。

将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版本新引入的官方包管理工具,它主要用于解决之前没有地方记录依赖包具体版本的问题,相比vendor、dep等包管理工具,更加便于依赖包的管理。

go.mod其实就是一个modules,关于modules的官方定义为:

modules是相关go包的集合,是源代码交换和版本控制的单元。

go命令直接支持使用modules,包括记录和解析对其他模块的依赖性。modules替换golang旧版本中基于GOPATH的方式,来指定使用哪些源文件。

modules和传统的GOPATH不同,不需要包含例如src,bin这样的子目录,一个源代码目录甚至是空目录都可以作为modules,只要其中包含有go.mod文件。

如何使用go.mod
1.首先将go的版本升级为1.11及以上
2.设置GO111MODULE

GO111MODULE有三个值:off, on和auto(默认值)。

GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
GO111MODULE=on,go命令行会使用modules,不会去GOPATH目录下查找。
GO111MODULE=auto,默认值,使用该方式时,go命令行将会根据当前目录来决定是否启用module功能。
包的版本控制

在使用go build、go test、go list、go tidy等命令时,go会自动更新go.mod文件,将项目依赖的包、包版本等依赖关系写入该文件。

使用mod进行包管理的另外一项重要功能就是包的版本控制。go.mod文件中的依赖内容,如下:

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括号里面的前面部分是包的名字,也就是项目package包中import时需要导入的依赖部分,而空格之后的是版本号,版本号遵循如下规律:

vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef
vX.0.0-yyyymmddhhmmss-abcdefabcdef
vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef
vX.Y.Z

也就是:版本号-时间戳-hash,当自己想要使用具体的版本时只需要指定版本号即可,没有版本tag的则需要找到对应commit的时间和hash值。而默认使用的是最新版本的package。

当前最新的iris版本为v12.2.0-alpha2,如果想使用v12.1.8版本的iris,需要怎么办呢?
只需要如下命令:

go mod edit -require="github.com/kataras/iris/v12@v12.1.8"

但是,这种方式,在下一次使用go tidy更新依赖关系的时候,又会更新成最新版本的iris,那么需要怎么办呢?
这就需要配合replace命令,将特定包替换为指定的版本号,参看下面小节"在go-mod中指定包的版本号"。

在go-mod中指定包的版本号

在go.mod中,使用replace指定包版本号。
比如将google.golang.org/grpc最新版本替换为指定的v1.26.0,可以在go.mod的最后面,添加如下信息:

replace google.golang.org/grpc => google.golang.org/grpc v1.26.0

然后,再运行go run或go build即可。

go mod常用命令

go.mod 提供了module、require、replace和exclude 四种管理包及依赖的方式。

module 语句,表示指定包的名字(项目路径)
require 语句,表示项目指定的依赖项模块
replace 语句,表示可以替换的依赖项模块
exclude 语句,表示可以忽略依赖项模块

使用go mod管理go包时,主要有以下一些命令:

其中,最常使用的命令有go init、go tidy等。

$go mod init 项目路径
go mod init初始化go.mod文件,go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。

$go mod tidy
go mod tidy 命令,删除go.mod中不需要的依赖、新增需要的依赖。使用该命令,项目中需要的依赖会自动生成 require 语句
参考

golang:如何在go-mod中指定包的版本号
go mod 指定版本_go.mod
golang包管理解决之道——go modules初探
解决go get命令下载包出问题
go命令教程

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/995379.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存