封尘网

让学习成为一种习惯!

关于GOPATH使用过程中一点小经验

本篇文章并不是总结怎么写代码的,而是在环境配置,依赖管理等方面,主要是新手入门时遇到的基础问题。

1、Golang开发中是否需要Gopath目录?

设置 GOPATH 有什么意义?是否一定要设置GOPATH目录?

在Go语言中,项目在其生命周期内的所有操作(编码、依赖管理、构建、测试等)都基本围绕着GOPATH目录进行的。

因为在Go1.11版本前,就是未使用GOMODULE的情况下,GOPATH目录主要是用来保存第三方包和我们项目代码的目录。不同点就是GOPATH同时也保存着依赖包的目录。

GOPATH作用

  • 保存第三方库,方便项目搜索引入依赖
  • 保存项目代码,是一个工作目录,好比JAVA的WORKSPACE
  • $GOPATH目录约定有三个子目录:bin,pkg,src
  • src目录保存依赖库代码(项目代码)
  • pkg存放当前系统版本下第三方包以.a结尾的静态库文件
  • bin就是可执行文件,有些第三方包如goimports,gopm等执行文件

[^]: 使用GOMODULE后代码可以不再保存在这里

而在使用GOMODULE模式后,GOPATH目录作用就显得不再这么纠结了。第三方的包同样会保存到GOAPTH目录下,但是我们的项目代码可以保存到其它的目录,这样分开保存依赖包和代码确实清爽了好多。

那么说来是不是GOPATH还是有必要的存在咯?其实不配置的话就会默认保存到我们系统用户家目录下,主要还是因为要保存依赖的第三方库。 说白了就是使用GOMODULE模式后可以设置也可以不设置任君选择。

这里还是要说明一点,不管是否使用新版本的GO[11.1后],都应该配置一个GOPATH目录方便管理依赖库,然后再建一个目录保存我们的项目代码。

2、第三方库的下载
由于在国内下载很多第三方的包都比较慢,或者甚至无法方法到golang.org官网。所以很多依赖库也是没法下载的。

  • 配置GOPROXY,需要配置GO111MODULE=on
  • 使用gopm替代go来下载第其它第三方包

GOPROXY配置:

export GO111MODULE=on
export GOPROXY=https://goproxy.io

这样就可以走GOPAOXY来下载第三方包了。

如何使用Goland IDE工具,打开项目就会自动检测go.mod里的依赖,同时执行go list -m -json 模块名 all 命令,并把依赖库缓存到$GOPATH/pkg/mod/cache/download目录,直接build或者运行程序时就会从缓存目录中把需要的第三方依赖包复制到$GOPATH/pkg/mod目录下。

说明

  • 模块名,就是在初始化go.mod 文件时,执行命令: go mod init <模块名>

使用gopm下载第三方包
前提条件:没有使用GO111MODULE模式,就是以前的情况。

GO111MODULE=off

如果GO111MODULE=on的情况下,就会把gopm代码拉到了$GOPATH/pkg/mod目录下,同时会提示有些版本号不匹配无法编译或者安装。

异常提示如下:

E:\Gopath>go get -v github.com/gpmgo/gopm
Fetching https://goproxy.io/github.com/gpmgo/gopm/@v/list
Fetching https://goproxy.io/github.com/codegangsta/cli/@v/list
Fetching https://goproxy.io/github.com/%21unknwon/goconfig/@v/list
Fetching https://goproxy.io/github.com/%21unknwon/com/@v/list
go: finding github.com/Unknwon/goconfig latest
Fetching https://goproxy.io/github.com/%21unknwon/goconfig/@latest
go: finding github.com/Unknwon/com latest
Fetching https://goproxy.io/github.com/%21unknwon/com/@latest
go: github.com/codegangsta/cli@v1.21.0: parsing go.mod: unexpected module path "github.com/urfave/cli"
go: github.com/Unknwon/com@v0.0.0-20190804042917-757f69c95f3e: parsing go.mod: unexpected module pat
h "github.com/unknwon/com"
go: error loading module requirements

原因:GO111MODULE开启的情况下,拉下来的代码会是新版本的,后面带的版本号就导致无法识别。

使用gopm是因为有些第三方库不好下载。

  • 拉取gopm代码
    go get -v -u github.com/gpmgo/gopm

  • 编译gopm代码
    go install github.com/gpmgo/gopm

执行install后就会产生一个gopm可执行的文件到$GOPATH/bin目录下,如果要直接可以执行就要加入到系统的环境变量中。

export $GOPATH/bin

通过gopm安装goimports[在Goland IDE]中可以一按Ctrl+S保存代码就会格式化好代码,并去掉不需要导入的包。

gopm get -g -v golang.org/x/tools/cmd/goimports

同样编译成二进制文件

gopm install golang.org/x/tools/cmd/goimports

如果使用了GO111MODULE模式的话下载goimports就简单多了,直接在Golnad IDE 工具中添加就会提示你是否下载。但是下载完是没有可执行文件的,需要执行install一下。

E:\Gopath\pkg\mod>go install -v golang.org/x/tools/cmd/goimports
Fetching https://goproxy.io/golang.org/x/tools/cmd/goimports/@v/list
Fetching https://goproxy.io/golang.org/x/tools/cmd/@v/list
Fetching https://goproxy.io/golang.org/x/tools/@v/list
go: finding golang.org/x/tools latest
Fetching https://goproxy.io/golang.org/x/tools/@latest

install后goimports执行文件就可以在$GOPATH/bin目录下找到了。

总结:
建议都启用GO111MODULE=on模式,加上GOPROXY可以很方便国内下载第三方包,减少手工下载一些包的麻烦,目前大部分项目都普遍加入了GO111MODULE支持。开发不应该耗太多时间在这些配置之中,把精力集中在代码上。

提醒:本文最后更新于 10 天前,文中所描述的信息可能已发生改变,请谨慎使用。