社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
golang的 GOPATH和vendor的搜索关系
基本规则
例子1:完全自包含项目
项目只有一个包,即main包,没有引用其他的包(golang自带的系统包除外)。
mkdir myproject
[~/myproject]$ cat main.go
package main
import "fmt"
func main() {
fmt.Printf("main::mainn");
foo()
}
[~/myproject]$ cat foo.go
package main
import "fmt"
func foo() {
fmt.Printf("main::foon");
}
[~/myproject]$ unset GOPATH
[~/myproject]$ go build
[~/myproject]$ ls -1
foo.go
main.go
myproject
<goproject>
|-- src
|-- myproject
|-- main.go
|-- foo.go
然后设置GOPATH=path/to/<goproject>,再运行go build myproject,这样就可以在任何目录下面编译,编译生成的可执行文件就在编译所在的目录下,而不是包源文件所在的目录。
例子2:引用了其他的包
基本规则:
import <package>
总是从$GOPATH/src目录下面搜索包,如果找不到就报错。
鉴于此,建议golang项目必须严格按照规范的目录结构组织,哪怕是前面这种自包含的项目。
例子3: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::mainn");
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下面都存在那么谁会优先使用呢。
结论是:
[~/<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怎么处理层级关系呢。
规则是:
举例:
[~/<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,那是怎么搜索的呢
总结
<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
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!