前言
本文为笔者所著 Go 语言基础系列之一,本文介绍笔者所认为的开发环境的最佳实践;
本文为作者原创作品,转载请注明出处;
GoPATH
Golang 通过 GoPATH 设置类库和源码的相对路径,所有 Go 所引用到的源码(包括第三方库的源码),都必须放置到该路径下;Golang 在 GoPATH 路径下约定了两个目录,
src
保存工程源码和第三方类库的源码,通常以1
2
3
4
5
6
7
8├──<GoPath>
└── src
└── <Project A>
├── main.go
└── ...
└── <Project B>
├── main.go
└── ...这样的目录结构组织项目;
- bin
保存构建好的二进制可执行文件;目录结构如下,1
2
3
4
5
6
7
8
9
10
11├──<GoPath>
└── bin
project a main.exe
...
└── src
└── <Project A>
├── project a main.go
└── ...
└── <Project B>
├── main.go
└── ...
构建两个完全隔离的工程
痛点,
Golang 通过 GoPath 环境变量设置了一个全局的路径,Go 约定,所有的项目的源码、第三方包都放置在 $GoPath/src
目录中的,并且共同引用同一个全局类库;这个非常不利于多项目的开发,因为通常各自独立的项目需要相互隔离,需要引用各自独立的类库;
方案,
Goland 提供了独立于项目的 Project GOPATH 设置,使得不同项目之间的 GOPATH 可以实现隔离;
首先,我们要清楚的是,Golang 要求,工程源码的路径必须为 $GoPath/src/<project name>
;现在,假设我们现在有两个独立的项目 a 和 b,那么,我们该如何通过 Goland 来创建两个完全隔离的项目呢?
- 通过 Goland 创建 a 工程,假设工程路径为
~/workspace/golang/a
; 设置 a 工程的 Project Path,如图,
注意,在 macos 的环境下,Golang 安装完成后,将会把全局的 Gopath 设置在
~/mac/go
路径下;这里,我们只需要通过 Project Path 设置工程 a 自己的 GoPath 即可,这里笔者的路径为~/workspace/golang/a
;检查,1
2
3
4
5
6
7
8
9
10
11$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/mac/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/mac/workspace/golang/a:/Users/mac/go"
...这里我们关注 GOPATH,它将 Project GOPATH 和 Global GOPATH 两个路径同时赋值给了环境变量 GOPATH;可见,Goland 实际上只是重新设置了 GOPATH,将全局的和项目自身的 GOPATH 合二为一同时赋值给了环境变量 GOPATH 而已;备注,上面的检查必须在 Goland 自己的 Termianl 中执行,因为 Project Path 只能在 Goland 自己的 Terminal 中才能生效。
- 在工程 a 中创建源码,hello.go,注意,根据 Golang 对源码的约定,所有的源码(包含第三方类库的源码)必须放置在
$GoPath/src
目录下,所以,这里,笔者源码的路径定义为$Project GoPath/src/a/hello.go
,如图, 唯一让笔者觉得别扭的地方是,目录结构中,有两个a
,工程名在路径中两次出现了,但是也没什么好奇怪的,第一个路径a
是Project GoPath
中的关键路径,第二个路径a
表示的是工程名; 构建测试,通过 Goland 的 Terminal 执行构建命令
go install
,1
2$ cd ~/workspace/golang/a/src/a/
$ go installgo install
会把工程 a 下面的 go 代码进行构建,并将构建好的二进制可执行文件生成到$Project GOPATH/bin/
目录中,1
2
3
4
5
6
7
8$ tree ~/workspace/golang/a
/Users/mac/workspace/golang/a
├── bin
│ └── a
└── src
└── a
├── hello.go
└── modules按照上述的方式构建 b 工程即可;
这样,我们便实现了两个不同工程间的完全隔离;总结,可以将公用的类库存放到$Global GoPath/src
中,然后将独立于工程的类库放置到$Project GoPath/src
中即可;