go语言的工作区是一个目录,下边有3个主要的文件件,src用于保存源码文件,pkg用于保存二进制库文件,bin用于保存二进制可执行文件。GOPATH就是工作区的根目录。

其他语言可能是一个项目使用一个工作区,但是go建议所有项目使用同一个工作区。一个典型的go工作区目录结构:

bin/
pkg/
src/
	project1/
		.git/
		package1/
		package2/
		main.go
		vendor/
		Gopkg.lock
		Gopkg.toml
	project2/
		.git
		...

项目在src目录下划分,代码仓库在每个项目下。package1和package2是项目project1的自定义的包,vendor用于存放project1项目的第三方代码。

Gopkg.lock和Gopkg.toml是使用Dep管理第三方库的版本相关信息和锁定。建议将所有第三方代码也提交到版本库中,因为有些第三方库下载慢或者需要翻墙才能下载。提交到代码库方便在新环境下获取。

mian.go是项目入口文件。也可以单独用一个文件夹安放,但是package的名字必须叫main。

编译命令

GOPATH如果不设定,将会提供一个默认值,可以使用go env查看。在Mac上默认值是/Users/[UserName]/go。

在GOPATH的根目录下运行go build project1,就可以编译project1项目。如果不指定输出文件,默认在当前文件夹(GOPATH)下生成一个project1的二进制可执行文件。

在GOPATH根目录下运行go install golearn1,project1项目将被编译并且生成project1的二进制文件在bin目录中。

Dep使用

在GOPATH下使用go get命令来安装Dep

go get -v -u github.com/golang/dep/cmd/dep

在项目目录下(注意不是在GOPATH的根目录下,要进入到具体项目,因为Dep管理的是一个具体项目的依赖),使用dep init命令初始化,完成后会生成两个文件Gopkg.lock,Gopkg.toml,前者是锁定文件,后者是依赖的第三方包信息,还有一个文件夹vendor,用于存放第三方源码。

在添加一个第三方包的时候使用dep ensure -add命令而不是go get

dep ensure -add github.com/bitly/go-simplejson

此时如果源码文件中还没有引入这个第三方包,这是常见的情况,则会出现一个警告:

"github.com/bitly/go-simplejson" is not imported by your project, and has been temporarily added to Gopkg.lock and vendor/.
If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/.

因此下一步便是在你的源码文件中引入这个包并使用。

另外一种使用方式是现在代码中引入第三方包

import "github.com/bitly/go-simplejson"

然后再使用dep ensure同步,这会自动下载第三方包。

如果使用GoLand IDE开发,第二种使用方式可能会遇到些问题,因为GoLand会自动删除没有被使用的引用。此时只要不保存源码文件,就不会触发GoLand的自动行为。

如果使用dep ensure命令的时候出现如下警告:

$ dep ensure
Warning: the following project(s) have [[constraint]] stanzas in Gopkg.toml:

  ✗  github.com/bitly/go-simplejson

However, these projects are not direct dependencies of the current project:
they are not imported in any .go files, nor are they in the 'required' list in
Gopkg.toml. Dep only applies [[constraint]] rules to direct dependencies, so
these rules will have no effect.

Either import/require packages from these projects so that they become direct
dependencies, or convert each [[constraint]] to an [[override]] to enforce rules
on these projects, if they happen to be transitive dependencies.

那个叉说明dep下载了这个文件的源码,但是项目中没有使用。这在项目的编译时候没有什么影响,但是如果vendor文件夹是提交到代码库的,未使用的文件会引起代码库项目变大,可以使用dep prune -v 命令清除。