Golang最被诟病的三个问题: module管理机制, 泛型, 错误处理
go mod 就是用来解决 module 管理机制
首先,把 go 的版本升级到 1.12.x. 可以用 go help mod
看到 go mod
的子命令
Note that support for modules is built into all the go commands,
not just 'go mod'. For example, day-to-day adding, removing, upgrading,
and downgrading of dependencies should be done using 'go get'.
See 'go help modules' for an overview of module functionality.
Usage:
go mod <command> [arguments]
The commands are:
download download modules to local cache (下载依赖包)
edit edit go.mod from tools or scripts (编辑go.mod)
graph print module requirement graph (打印模块依赖图)
init initialize new module in current directory (在当前目录初始化mod)
tidy add missing and remove unused modules (拉取缺少的模块,移除不用的模块)
vendor make vendored copy of dependencies (将依赖复制到vendor下)
verify verify dependencies have expected content (验证依赖是否正确)
why explain why packages or modules are needed (解释为什么需要依赖)
Use "go help mod <command>" for more information about a command.
其次,在项目目录下,一般是 main.go(func main()所在的源文件)
所在的目录下,执行 go mod init 项目名
,这个命令会在执行命令的当前目录下生成一个 go.mod
文件,内容如下:
D:\GOProject\src\go-printcloud-authemail>go mod init go-printcloud-authemail
go: creating new go.mod: module go-printcloud-authemail
go: copying requirements from Godeps\Godeps.json
......
设置 GO111MODULE
- GO111MODULE = off,go命令行将不会支持 module功能,寻找依赖包的方式将会沿用旧版本那种通过 vendor 目录或者 GOPATH 模式来查找。
- GO111MODULE = on,go命令行会使用 modules,而一点也不会去 GOPATH 目录下查找。
GO111MODULE = auto,默认值,go命令行将会根据当前目录来决定是否启用 module 功能。这种情况下可以分为两种情形:
- 当前目录在 GOPATH/src 之外且该目录包含 go.mod文件
- 当前文件在包含 go.mod 文件的目录下面。
$GOPATH/pkg
,允许同一个 package 多个版本并存,且多个项目可以共享缓存的 module。
最重要的一步来了,因为众所周知的原因,很多包不能直接下载,可以用 proxy,如果找不到 proxy,那么只能用 replace,用文本编辑器打开 go.mod,加入如下内容:
replace (
golang.org/x/text => github.com/golang/text latest
golang.org/x/net => github.com/golang/net latest
golang.org/x/crypto => github.com/golang/crypto latest
golang.org/x/tools => github.com/golang/tools latest
golang.org/x/sync => github.com/golang/sync latest
golang.org/x/sys => github.com/golang/sys latest
)
然后执行 go mod tidy
这个命令会把 latest 自动替换成最新的版本号,例子:
replace (
golang.org/x/crypto => github.com/golang/crypto v0.0.0-20191011191535-87dc89f01550
golang.org/x/sys => github.com/golang/sys v0.0.0-20191024073052-e66fe6eb8e0c
golang.org/x/text => github.com/golang/text v0.3.2
golang.org/x/time => github.com/golang/time v0.0.0-20191024005414-555d28b269f0
google.golang.org/genproto => github.com/google/go-genproto v0.0.0-20191009194640-548a555dbc03
google.golang.org/grpc => github.com/grpc/grpc-go v1.24.0
)
如果是老项目,一般不会那么容易就成功,会提示各种错误,比如出现如下错误:
go: github.com/Sirupsen/logrus@v0.0.0-20190423093405-5521996833c0: parsing go.mod: unexpected module path "github.com/sirupsen/logrus"
go: error loading module requirements
其实就是提示 Sirupsen/logrus 其实应该是 sirupsen/logrus 路径问题,所以我们手动修改go.mod。然后再执行 go mod tidy ,如果出错,看是路径还是版本或者其它问题,再把需要的版本加入修改go.mod 文件,反复几次,最后就可以成功了。我最后的go.mod 是这样的:
module go-printcloud-authemail
go 1.12
replace (
github.com/Sirupsen/logrus v1.0.5 => github.com/sirupsen/logrus v1.0.5
github.com/Sirupsen/logrus v1.3.0 => github.com/Sirupsen/logrus v1.0.6
github.com/Sirupsen/logrus v1.4.0 => github.com/sirupsen/logrus v1.0.6
golang.org/x/crypto => github.com/golang/crypto v0.0.0-20191011191535-87dc89f01550
golang.org/x/net => github.com/golang/net v0.0.0-20191028085509-fe3aa8a45271
golang.org/x/sync => github.com/golang/sync v0.0.0-20190911185100-cd5d95a43a6e
golang.org/x/sys => github.com/golang/sys v0.0.0-20191024073052-e66fe6eb8e0c
golang.org/x/text => github.com/golang/text v0.3.2
golang.org/x/time => github.com/golang/time v0.0.0-20191024005414-555d28b269f0
golang.org/x/tools => github.com/golang/tools v0.0.0-20191029041327-9cc4af7d6b2c
golang.org/x/xerrors => github.com/golang/xerrors v0.0.0-20191011141410-1b5146add898
google.golang.org/genproto => github.com/google/go-genproto v0.0.0-20191009194640-548a555dbc03
google.golang.org/grpc => github.com/grpc/grpc-go v1.24.0
)
require (
github.com/360EntSecGroup-Skylar/excelize v0.0.0-20190407060441-4e7d93a77796
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/Sirupsen/logrus v1.4.0
github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0 // indirect
github.com/emersion/go-imap v1.0.0
github.com/emersion/go-message v0.10.4
github.com/emersion/go-sasl v0.0.0-20190704090222-36b50694675c // indirect
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 // indirect
github.com/go-sql-driver/mysql v0.0.0-20190510102335-877a9775f068 // indirect
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce // indirect
github.com/jinzhu/gorm v0.0.0-20180625050753-0fd395ab37ae
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect
github.com/jinzhu/now v1.1.1 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/lib/pq v0.0.0-20190507191818-2ff3cb3adc01 // indirect
github.com/magiconair/properties v1.8.0 // indirect
github.com/martinlindhe/base36 v1.0.0 // indirect
github.com/mattn/go-sqlite3 v1.11.0 // indirect
github.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675 // indirect
github.com/onsi/ginkgo v1.10.2 // indirect
github.com/onsi/gomega v1.7.0 // indirect
github.com/pelletier/go-toml v1.2.0 // indirect
github.com/robfig/cron v1.2.0
github.com/sirupsen/logrus v1.4.2 // indirect
github.com/spf13/afero v1.1.1 // indirect
github.com/spf13/cast v1.2.0
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec // indirect
github.com/spf13/pflag v0.0.0-20180601132542-3ebe029320b2 // indirect
github.com/spf13/viper v0.0.0-20180507071007-15738813a09d // indirect
github.com/sunmi-OS/gocore v1.0.1-0.20190723035437-2c216bcac93b
github.com/urfave/cli v0.0.0-20190203184040-693af58b4d51
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
gopkg.in/yaml.v2 v2.2.3-0.20190319135612-7b8349ac747c // indirect
)
最后,附上常用的replace列表:
golang.org/x/text => github.com/golang/text latest
golang.org/x/net => github.com/golang/net latest
golang.org/x/crypto => github.com/golang/crypto latest
golang.org/x/tools => github.com/golang/tools latest
golang.org/x/sync => github.com/golang/sync latest
golang.org/x/sys => github.com/golang/sys latest
cloud.google.com/go => github.com/googleapis/google-cloud-go latest
google.golang.org/genproto => github.com/google/go-genproto latest
golang.org/x/exp => github.com/golang/exp latest
golang.org/x/time => github.com/golang/time latest
golang.org/x/oauth2 => github.com/golang/oauth2 latest
golang.org/x/lint => github.com/golang/lint latest
google.golang.org/grpc => github.com/grpc/grpc-go latest
google.golang.org/api => github.com/googleapis/google-api-go-client latest
google.golang.org/appengine => github.com/golang/appengine latest
golang.org/x/mobile => github.com/golang/mobile latest
golang.org/x/image => github.com/golang/image latest
cloud.google.com/go => github.com/googleapis/google-cloud-go v0.34.0
github.com/go-tomb/tomb => gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7
go.opencensus.io => github.com/census-instrumentation/opencensus-go v0.19.0
go.uber.org/atomic => github.com/uber-go/atomic v1.3.2
go.uber.org/multierr => github.com/uber-go/multierr v1.1.0
go.uber.org/zap => github.com/uber-go/zap v1.9.1
google.golang.org/api => github.com/googleapis/google-api-go-client v0.0.0-20181220000619-583d854617af
google.golang.org/appengine => github.com/golang/appengine v1.3.0
google.golang.org/genproto => github.com/google/go-genproto v0.0.0-20181219182458-5a97ab628bfb
google.golang.org/grpc => github.com/grpc/grpc-go v1.17.0
gopkg.in/alecthomas/kingpin.v2 => github.com/alecthomas/kingpin v2.2.6+incompatible
gopkg.in/mgo.v2 => github.com/go-mgo/mgo v0.0.0-20180705113604-9856a29383ce
gopkg.in/vmihailenco/msgpack.v2 => github.com/vmihailenco/msgpack v2.9.1+incompatible
gopkg.in/yaml.v2 => github.com/go-yaml/yaml v0.0.0-20181115110504-51d6538a90f8
labix.org/v2/mgo => github.com/go-mgo/mgo v0.0.0-20160801194620-b6121c6199b7
launchpad.net/gocheck => github.com/go-check/check v0.0.0-20180628173108-788fd7840127
强强强