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

 更新时间:2023年09月18日 10:00:07   作者:love666666shen  
这篇文章主要介绍了go与go mod命令使用方式以及遇到的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

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

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

jwt和iris版本更新问题

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

iris版本更新引发的context问题

通过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方法:

go-impalax的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 mod命令与解释

其中,最常使用的命令有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函数式选项(Functional Options)模式

    详解Golang函数式选项(Functional Options)模式

    什么是函数式选项模式,为什么要这么写,这个编程模式解决了什么问题呢?其实就是为了解决动态灵活的配置不同的参数的问题。下面通过本文给大家介绍Golang函数式选项(Functional Options)模式的问题,感兴趣的朋友一起看看吧
    2021-12-12
  • Golang关键字defer的用法详解

    Golang关键字defer的用法详解

    defer是Go里面的一个关键字,用在方法或函数前面,作为方法或函数的延迟调用。这篇文章主要为大家介绍了defer的简单使用,需要的可以参考一下
    2023-05-05
  • Go中如何使用set的方法示例

    Go中如何使用set的方法示例

    这篇文章主要介绍了Go中如何使用set的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • golang 输出重定向:fmt Log,子进程Log,第三方库logrus的详解

    golang 输出重定向:fmt Log,子进程Log,第三方库logrus的详解

    这篇文章主要介绍了golang 输出重定向:fmt Log,子进程Log,第三方库logrus的详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Go type关键字(类型定义与类型别名的使用差异)用法实例探究

    Go type关键字(类型定义与类型别名的使用差异)用法实例探究

    这篇文章主要为大家介绍了Go type关键字(类型定义与类型别名的使用差异)用法实例探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Go内置零值标识符zero

    Go内置零值标识符zero

    大家学习和使用 Go 语言时,有一个神奇的概念:零值(zero-values),所以本文想给大家分享一个关于零值的新提案,目测已经八九不离十了
    2023-08-08
  • Golang pprof监控之cpu占用率统计原理详解

    Golang pprof监控之cpu占用率统计原理详解

    经过前面的几节对pprof的介绍,对pprof统计的原理算是掌握了七八十了,但唯独还没有分析pprof 工具是如何统计cpu使用情况的,今天我们来分析下这部分
    2023-04-04
  • go语言版的ip2long函数实例

    go语言版的ip2long函数实例

    这篇文章主要介绍了go语言版的ip2long函数,实例分析了Go语言实现的ip2long函数技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go语言入门Go Web Fiber框架快速了解

    Go语言入门Go Web Fiber框架快速了解

    这篇文章主要为大家介绍了Go语言入门Go Web Fiber框架的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • 浅谈Go切片的值修改是否会覆盖数组的值 

    浅谈Go切片的值修改是否会覆盖数组的值 

    本文主要介绍了浅谈Go切片的值修改是否会覆盖数组的值,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 
    2022-02-02

最新评论