内容简介:golang的 GOPATH和vendor的搜索关系基本规则例子1:完全自包含项目
golang的 GOPATH和vendor的搜索关系
基本规则
-
- 所有的 go 文件都是必须组织成包的形式,放在相应文件夹下:
- 1.1 建议包名和文件夹名字相同;虽然也可以不同,但会引发使用误解。
-
1.2 对于主程序包,也需要放在文件夹下面,注意:
- 1.2.1 不建议使用main作为文件夹名,虽然这个包名是main。
- 1.2.2 也不建议使用src作为文件名,尽管这是允许的,但是会引发误解。
- 1.2.3 建议使用项目名字作为包名。
-
- go build命令如果不带参数,就是build当前包,当前目录所在的包,即当前目录下面的所有go文件。
- 1.2 如果go build指定了目标包,那么就会从GOPATH路径下面搜索包,如果找不到,就报失败;哪怕当前路径就在目标包里,但是GOPATH没有包含,也会报失败。
- 1.2 如果GOPATH没有设置,其缺省路径就是$HOME/gp
例子1:完全自包含项目
项目只有一个包,即main包,没有引用其他的包(golang自带的系统包除外)。
-
1.新建文件夹,例如myproject。
mkdir myproject
-
- 编辑项目文件
[~/myproject]$ cat main.go package main import "fmt" func main() { fmt.Printf("main::main\n"); foo() } [~/myproject]$ cat foo.go package main import "fmt" func foo() { fmt.Printf("main::foo\n"); }
-
- 编译项目
[~/myproject]$ unset GOPATH [~/myproject]$ go build [~/myproject]$ ls -1 foo.go main.go myproject
- 直接进入项目目录运行 go build,即编译当前包。
- 不需要设置GOPATH值,缺省就是~/go,因为这是一个自包含项目,不需要引用GOPATH的任何值。
- 编译生成的可执行文件名就是项目文件夹名。
- 注意当前目录必须是项目文件所在目录,因为go build没有指定目标包,缺省编译当前目录包;如果不是就不行,那得必须按照golang的项目组织规范来组织。
<goproject> |-- src |-- myproject |-- main.go |-- foo.go
然后设置GOPATH=path/to/<goproject>,再运行go build myproject,这样就可以在任何目录下面编译,编译生成的可执行文件就在编译所在的目录下,而不是包源文件所在的目录。
例子2:引用了其他的包
基本规则:
-
1.
import <package>
总是从$GOPATH/src目录下面搜索包,如果找不到就报错。- 1.2 并不会从当前目录下面去搜索,也不会从源文件相对目录下面去搜索。
- 1.GOPATH可以包含多个路径,中间用冒号(:)隔开,就像PATH一样。
鉴于此,建议golang项目必须严格按照规范的目录结构组织,哪怕是前面这种自包含的项目。
例子3:vendor目录的使用
基本规则:
-
1.使用vendor,项目必须严格按照规范的目录结构组织。
- 1.2 即使像例子1中自包含的项目也不能使用vendor
- 2.vender需要在原文件下面创建vendor目录,然后把vendor的文件包放入vendor目录即可,在引用的时候不需要指定vendor路径。
[~/]$ find <goproject> <goproject> <goproject>/src <goproject>/src/myproject <goproject>/src/myproject/main.go <goproject>/src/myproject/vendor <goproject>/src/myproject/vendor/mydeps <goproject>/src/myproject/vendor/mydeps/dep1.go [~/<goproject>]$ cat <goproject>/src/myproject/main.go package main import "fmt" import "mydeps" func main() { fmt.Printf("main::main\n"); mydeps.Foo() } [~/<goproject>]$ cat <goproject>/src/myproject/vendor/mydeps/dep1.go package mydeps import "fmt" func Foo() { fmt.Println("in mydeps::Foo") }
例子4:vendor和GOPATH谁优先使用
如果一个包在vendor和GOPATH下面都存在那么谁会优先使用呢。
结论是:
-
- 优先使用vendor目录下面的包。
-
- 如果vendor下面没有搜索到,再搜索GOPATH下面的包。
-
-
要么完整使用vendor下面的包,要么完整使用GOPATH下面的包,不会混合使用:
-3.1 假如一个函数定义再GOPATH下面的包里,而没有定义在vendor路径下的同名包里,那么调用者就会报函数未定义错误,因为调用者如果找到有vendor路径下面的包,就不会去找GOPATH下面的包了。
-
[~/<goproject>]$ find src src src/myproject src/myproject/main.go src/myproject/vendor src/myproject/vendor/mydeps src/myproject/vendor/mydeps/dep1.go src/mydeps src/mydeps/dep1.go
包mydeps在vendor目录下面和GOPATH路径下面都存在了,那么main.go引用的时候只会引用vendor下面的mydeps(src/myproject/vendor/mydeps),而忽略GOPATH下面的mydeps包(src/mydeps)。
例子5:vendor的层级搜索
前面提到GOPATH和PATH类似,可以包含多个路径,中间用分号隔开,go在搜索包的时候会按手续从前往后搜搜。那么vendor怎么处理层级关系呢。
规则是:
- 1.从引用文件所在的vendor路径下面搜索。
- 2.如果没有找到,那么从上层目录的vendor路径下面搜索。
- 3.直到src的vendor路径下面搜索。
举例:
[~/<goproject>]$ find ./ ./src ./src/myproject ./src/myproject/myproject ./src/myproject/main.go ./src/mydep ./src/mydep/mydep1 ./src/mydep/mydep1/mydep.go ./src/mydep/mydep1/vendor ./src/mydep/mydep1/vendor/myvendor1 ./src/mydep/mydep1/vendor/myvendor1/myvendor.go ./src/mydep/mydep.go ./src/mydep/vendor ./src/mydep/vendor/myvendor ./src/mydep/vendor/myvendor/myvendor.go
如果src/mydep/mydep1/mydep.go引用了myvendor1和myvendor,那是怎么搜索的呢
-
先从src/mydep/mydep1/vendor下面搜索myvendor1。
找到了,直接使用。 -
先从src/mydep/mydep1/vendor下面搜索myvendor。
发现没有找到,那么从上层路径搜索,即: -
先从src/mydep/vendor下面搜索myvendor。
找到了,直接使用。 -
如果还没有找到,那么继续向上一级搜索,即
src/vendor - 如果找到了,则使用;如果还没有找到,那么继续从GOPATH里搜索,直到找到或者失败。
总结
- 建议golang项目严格按照golang项目组织方式,即使只是一个自包含的项目。
<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目录放在源文件目录同级,下面包含各个包。
3.1 vendor的搜索优先于GOPATH的搜索。
3.2 vendor按照路径深度向外按顺序搜索,直到$GOPATH/src/vendor为止。
以上所述就是小编给大家介绍的《golang的 GOPATH和vendor的搜索关系》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- R-MeN: 个性化搜索的关系记忆网络Embedding
- 框架与RTTI的关系,RTTI与反射之间的关系
- 如何用循环关系网络机智地解决数独类关系推理任务?
- 【mybatis xml】数据层框架应用--Mybatis(三)关系映射之一对一关系映射
- Hibernate 关系映射整理
- Hibernate 关系映射整理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
现代操作系统(原书第4版)
[荷] Andrew S. Tanenbaum、[荷] Herbert Bos / 陈向群、马洪兵 等 / 机械工业出版社 / 2017-7 / 89.00
Andrew S. Tanenbaum教授编写的教材《现代操作系统》现在已经是第4版了。第4版在保持原有特色的基础上,又增添了许多新的内容,反映了当代操作系统的发展与动向,并不断地与时俱进。 对比第3版,第4版有很多变化。一些是教材中多处可见的细微变化,一些是就某一功能或机制增加了对最新技术的介绍,如增加了futex同步原语、读–复制–更新(Read-Copy-Update)机制以及6级RA......一起来看看 《现代操作系统(原书第4版)》 这本书的介绍吧!