Golang vendor文件夹使用详解

olzhy · · 3111 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

<strong>1 提出问题</strong> <br /> 我们知道,一个工程稍大一点,通常会依赖各种各样的包。而Go使用统一的GOPATH管理依赖包,且每个包仅保留一个版本。而不同的依赖包由各自的版本工具独立管理,所以当所依赖的包在新版本发生接口变更或删除时,会面临很多问题。 为避免此类问题,我们可能会为不同的工程设置不同的GOPATH,或者更改依赖包路径名称。这样手动维护起来也很头疼。 <br /> <strong>2 解决问题</strong> <br /> Go 1.5引入了vendor文件夹,其对语言使用,go命令没有任何影响。若某个路径下边包含vendor文件夹,则在某处引用包时,会优先搜索vendor文件夹下的包。 在Go 1.5开启该项特性需设置GO15VENDOREXPERIMENT=1,而从Go 1.6开始,该项特性默认开启。 <br /> <strong>3 使用方式</strong> <br /> 3.1 vendor搜索方式 vendor包的搜索方式为:自包引用处,从其所在文件夹查询是否有vendor文件夹包含所引用包;若没有,然后从其所在文件夹的上层文件夹寻找是否有vendor文件夹包含所引用包,若没有,则再搜索上层文件夹的上层文件夹...,直至搜索至$GOPATH/src并搜索完成时止。 例如,如下代码中,$GOPATH/src/x/y/z/main.go引用了包"v",则不论vendor/v/v.go置于src/,src/x/,src/x/y/,src/x/y/z/中任意一个文件夹下,均可以找到。 <code>$ cat $GOPATH/src/x/y/z/main.go</code> <pre> package main import ( "v" ) func main() { v.V() } </pre> <code>$ cat vendor/v/v.go</code> <pre> package v import "fmt" func V() { fmt.Println("I'm a vendor test") } </pre> <code>$ go run main.go</code> <pre>I'm a vendor test</pre> 当vendor存在嵌套时,若不同的vendor文件夹包含相同的包,且该包在某处被引用,寻找策略仍遵循如上规则。即从包引用处起,逐层向上层文件夹搜索,首先找到的包即为所引,也就是从$GOPATH/src来看,哪个vendor包的路径最长,使用哪个。 如下代码中,$GOPATH/src/x/y/z/main.go所在工程有两个vendor文件夹(分别位于$GOPATH/src/x/vendor/v/,$GOPATH/src/x/y/z/vendor/v/)包含相同的包"v",目录树为: <code>$ tree $GOPATH/src</code> <pre> src └ x ├ vendor │ └ v │ └ v.go └ y └ z ├ vendor │ └ v │ └ v.go └ main.go </pre> <code>$ cat $GOPATH/src/x/vendor/v/v.go</code> <pre> package v import "fmt" func V() { fmt.Println("I'm a vendor test, My path is x/vendor/v/") } </pre> <code>$ cat $GOPATH/src/x/y/z/vendor/v/v.go</code> <pre> package v import "fmt" func V() { fmt.Println("I'm a vendor test, My path is x/y/z/vendor/v/") } </pre> 输出为: <code>$ go run main.go</code> <pre> I'm a vendor test, My path is x/y/z/vendor/v/ </pre> 可以看到,真正调用的是$GOPATH/src/x/y/z/vendor/v/v.go。 3.2 vendor使用规约 使用vendor时,建议遵循如下两条规约。 a) 当欲将某包vendor时,可能想将所有依赖包均vendor; b) 尽量将vendor依赖包结构扁平化,不要vendor套vendor。 如下示例代码演示vendor扁平化使用。 main.go位于$GOPATH/src/github.com/olzhy/test下。 <pre> package main import ( "strings" "sync" "time" "github.com/z" "github.com/y" "golang.org/z" ) ... </pre> $GOPATH/src/github.com/olzhy/test目录树。 <pre> ├─ main.go └─ vendor ├─ github.com │ ├─ x │ └─ y └─ golang.org └─ z </pre> 原文地址:https://leileiluoluo.com/posts/golang-vendoring.html

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3111 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传