配置vscode的go开发环境,可能花了很多人不少时间,但是一旦熟悉起来,再回头来看时就会觉得简单很多,不管是配置安装还是工程目录。这一篇作为安装好vscode和go环境变量之后的第二篇可以帮助我等新手向前迈出一大步,理解了之后,在以后的使用之中可以避免大多数问题。

这一篇主要介绍两个有关联内容:gopath、module管理包的区别,以及将我们的项目放到一台新机器上编译运行的问题。

一、gopath下的包管理

在上一篇VSCode安装配置Go开发环境时,安装go开发工具包这一步很容易失败,其中介绍的第二种解决办法就是将这些包提前下载了放在指定路径之下。这个指定路径其实就是gopath下第三方包的路径。下面举例来说。

我们在程序中假如要用到一个第三包中的工具,例如"github.com/tidwall/gjson"这个包(一个解析json数据格式的包),我们就需要在程序导入这个包import "github.com/tidwall/gjson",但是这个包并不是在本地,而是在github上,因此我们需要现在终端执行go get "github.com/tidwall/gjson"命令,将这个包拉取到本地,命令执行结束之后会在gopath/src目录下看到一个github.com的目录,该目录就是存放其他包的目录,也即前面说的指定路径。

再比如这个包"go.uber.org/zap/zapcore"(一个与日志有关的包),我们要在程序中使用它里面的函数时,就要导入它import "go.uber.org/zap/zapcore",同样我们需要先把这个包使用go get命令拉到本地,这时gopath/src目录下面会有一个go.uber.org的目录,里面放的就是所有以go.uber.org开头的包。

这就是gopath的包管理:需要使用的包先以go get命令下载到本地,这些包默认都放在gopath/src目录下面,和我们的项目处在同级目录下。在导入包、编译的时候都会从src下面去查找这些包。

但是由于github或者go.uber等访问很慢的问题,基本上go get命令都会执行失败;当然如果你已经成功配置好了vscode的开发环境,并且不是通过搭梯子的方式,那么执行go get命令也不会失败的。

原因就是既然已经配置好了开发环境,那么必定已经安装好了go开发工具包,这些包同样都是放在github或者golang.org上面,和go get命令要下载的包放在同样的位置。

如果go get失败,和上一篇讲的方法一样,设置一下GOPROXY变量吧。

go env -w GOPROXY=https://goproxy.cn,direct 二、go mod 包管理

使用go mod的好处就是:

1、可以在任意位置建立项目,而不必在gopath的src目录下面2、可以不用再go get手动下载第三方包3、可以将第三方包用一条命令放到自己的项目里面,而不是在src目录下面

使用前的准备:
使用go env命令查看下面两个变量的值是否是这样,不是的话就执行下面的两条命令;如果执行失败,使用set GO111MODULE=auto执行,因为go env命令不能覆盖已有的变量值。

go env -w GO111MODULE=autogo env -w GOPROXY=https://goproxy.cn,direct

准备工作做好了,就可以直接使用了,下面以一个示例来介绍go mod。

1、随便找个位置建立项目
比如在桌面上建立hello文件夹,美满的橘子建立main.go文件,文件代码如下:
main.go

package main //main包import("fmt"world "hello/world" //导入world包,等会建立"github.com/tidwall/gjson" //导入前面说的第三方包,这个包可以解析json数据)func main(){fmt.Printf("hello ") world.Pworld() //调用world包的函数Pworlddata := `{"name":"gomod","birth":"today"}` //json格式的字符串name := gjson.GetBytes([]byte(data), "name").Str //使用gjson取name的值fmt.Printf("name is :%s\n",name)}

2、建立world包
在hello文件夹里面建立world文件夹,world文件夹下面建立world.go文件,代码如下:
world.go

package world //world包,包名可以不和文件或者文件名一样import("fmt")func Pworld(){ //注意,如果函数要给其他包的函数使用,就要大写首字母fmt.Println("world !!!")}

3、运行代码

在终端依次执行:cd desktop/hello //进入到项目路径go mod init hello //初始化modulego run main.go //运行程序

第一次执行的时候使用go mod init 项目名,会生成go.mod文件,运行后还会生成go.sum文件,含义就不说了。之后更新代码或者又新导入其他包的时候,只需执行go mod tidy命令即可,而无需再init一次。

我的执行结果:

这时我们进入到hello文件下面,发现里面并没有"github.com/tidwall/gjson"这个第三方包,这是因为go mod命令下载的包默认缓存在gopath里某个目录中。
执行:

go mod vendor

之后就会在hello里面看见一个vendor文件夹,里面放的就是gjson包。此时已经实现所有包都放在我们自己的项目里面,即使将项目拿到其他机器上,只要其他机器安装go了环境,就可以顺利的执行。

三、放到其他机器上运行

使用module管理的包的话,执行go mod vendor命令即可将依赖的所有包都放到项目里的vendor目录下,此时可以直接将项目移到其他机器上使用go run main.go运行。

下面主要介绍使用gopath管理的包该如何运行在远程服务器上。

前面说到,gopath管理的包放在与项目同目录的src之下,可能是github.com,也可能是go.uber.org等等,这时就需要手动将自己项目所依赖的所有包拿出来放到自己项目之下了。

至于放在那个文件夹下,这里先说一下import
我们从import "github.com/tidwall/gjson"语句以及gopath管理的包路径,可以猜测,导入的第三方包,是从gopath/src下开始查找的,因此github.com对应src下的github.com文件夹,tidwall对应github.com下的tidwalll文件夹…也就是说导入包是从src目录开始,根据路径来查找。

比如我们导入我们自己的world包时import hello/world,从hello写起是因为hello是我们的i项目,位于src之下,直接写import world不行,因为查找这个包是从src开始。

了解了import之后,再来说我们将自己项目所依赖的包拿出来后放哪里吧,想必不用我说也知道该放哪里了,但是会很麻烦。以上只是我的猜测,因为我一直使用的是module管理,对于gopath除了手动拿出依赖的包,可能还有更好的方式,大家自己探索吧。

四、go mod使用 初始化模块go mod init <项目模块名称>依赖关系处理,根据go.mod文件go mod tidy将依赖包复制到项目下的 vendor目录。go mod vendor如果包被屏蔽(墙),可以使用这个命令,随后使用go build -mod=vendor编译显示依赖关系go list -m all显示详细依赖关系go list -m -json all下载依赖go mod download [path@version][path@version]是非必写的作者:布衣码农链接:https://www.jianshu.com/p/1da8b06d7b10来源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。