基本规则
- 所有的go文件都是必须组织成包的形式,放在相应文件夹下:
- 建议包名和文件夹名字相同;虽然也可以不同,但会引发使用误解。
- 对于主程序包,也需要放在文件夹下面,注意:
- 不建议使用main作为文件夹名,虽然这个包名是main。
- 也不建议使用src作为文件名,尽管这是允许的,但是会引发误解。
- 建议使用项目名字作为包名。
- go build命令如果不带参数,就是build当前包,当前目录所在的包,即当前目录下面的所有go文件。
import “fmt”
func main() { fmt.Printf(“main::main\n”); foo() }
$ cat foo.go package main
import “fmt”
func foo() { fmt.Printf(“main::foo\n”); }
$ ls -1 foo.go main.go myproject
1. 直接进入项目目录运行 go build,即编译当前包。1. 不需要设置GOPATH值,缺省就是~/go,因为这是一个自包含项目,不需要引用GOPATH的任何值。1. 编译生成的可执行文件名就是项目文件夹名。1. 注意当前目录必须是项目文件所在目录,因为go build没有指定目标包,缺省编译当前目录包;如果不是就不行,那得必须按照golang的项目组织规范来组织。然后设置GOPATH=path/to/<goproject>,再运行go build myproject,这样就可以在任何目录下面编译,编译生成的可执行文件就在编译所在的目录下,而不是包源文件所在的目录。<a name="N8LfV"></a># 例子2:引用了其他的包基本规则:- `import <package>`总是从$GOPATH/src目录下面搜索包,如果找不到就报错。- 并不会从当前目录下面去搜索,也不会从源文件相对目录下面去搜索。- GOPATH可以包含多个路径,**中间用冒号(:)隔开**,就像PATH一样。鉴于此,建议golang项目必须严格按照规范的目录结构组织,哪怕是前面这种自包含的项目。<a name="cdnv4"></a># 例子3:vendor目录的使用基本规则:- 使用vendor,项目必须严格按照规范的目录结构组织。- 即使像例子1中自包含的项目也不能使用vendor- vender需要在原文件下面创建vendor目录,然后把vendor的文件包放入vendor目录即可,在引用的时候不需要指定vendor路径。<a name="m7WLY"></a># 例子4:vendor和GOPATH谁优先使用如果一个包在vendor和GOPATH下面都存在那么谁会优先使用呢。<br />结论是:1. 优先使用vendor目录下面的包。1. 如果vendor下面没有搜索到,再搜索GOPATH下面的包。1. 要么完整使用vendor下面的包,要么完整使用GOPATH下面的包,不会混合使用:1. 假如一个函数定义再GOPATH下面的包里,而没有定义在vendor路径下的同名包里,那么调用者就会报函数未定义错误,因为调用者如果找到有vendor路径下面的包,就不会去找GOPATH下面的包了。<a name="wQPfg"></a># 例子5:vendor的层次搜索前面提到GOPATH和PATH类似,可以包含多个路径,中间用分号隔开,go在搜索包的时候会按手续从前往后搜搜。那么vendor怎么处理层级关系呢。<br />规则是:- 从引用文件所在的vendor路径下面搜索。- 如果没有找到,那么从上层目录的vendor路径下面搜索。- 直到src的vendor路径下面搜索。<a name="r4nEB"></a># 总结1. 建议golang项目严格按照golang项目组织方式,即使只是一个自包含的项目。```bash<goproject>|-- src|-- mainpackage|-- XXX.go|-- YYY.go|-- vendor|-- deppackage1|-- XXX1.go|-- YYY1.go|-- vendor|-- deppackage2|-- XXX2.go|-- YYY2.go|-- vendor|-- VVV1.go|-- VVV2.go|-- vendor
- GOPATH使用分号(:)隔开的多个路径。
go编译的时候会从GOPATH/src目录下面搜索import的包。 vender目录放在源文件目录同级,下面包含各个包。
