基本规则

  • 所有的go文件都是必须组织成包的形式,放在相应文件夹下:
    • 建议包名和文件夹名字相同;虽然也可以不同,但会引发使用误解。
    • 对于主程序包,也需要放在文件夹下面,注意:
      • 不建议使用main作为文件夹名,虽然这个包名是main。
      • 也不建议使用src作为文件名,尽管这是允许的,但是会引发误解。
      • 建议使用项目名字作为包名。
  • go build命令如果不带参数,就是build当前包,当前目录所在的包,即当前目录下面的所有go文件。
    • 如果go build指定了目标包,那么就会从GOPATH路径下面搜索包,如果找不到,就报失败;哪怕当前路径就在目标包里,但是GOPATH没有包含,也会报失败。
    • 如果GOPATH没有设置,其缺省路径就是$HOME/gp

      例子1:完全自包含项目

      项目只有一个包,即main包,没有引用其他的包(golang自带的系统包除外)。 ```bash $ cat main.go package main

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. 1. 直接进入项目目录运行 go build,即编译当前包。
  2. 1. 不需要设置GOPATH值,缺省就是~/go,因为这是一个自包含项目,不需要引用GOPATH的任何值。
  3. 1. 编译生成的可执行文件名就是项目文件夹名。
  4. 1. 注意当前目录必须是项目文件所在目录,因为go build没有指定目标包,缺省编译当前目录包;如果不是就不行,那得必须按照golang的项目组织规范来组织。
  5. 然后设置GOPATH=path/to/<goproject>,再运行go build myproject,这样就可以在任何目录下面编译,编译生成的可执行文件就在编译所在的目录下,而不是包源文件所在的目录。
  6. <a name="N8LfV"></a>
  7. # 例子2:引用了其他的包
  8. 基本规则:
  9. - `import <package>`总是从$GOPATH/src目录下面搜索包,如果找不到就报错。
  10. - 并不会从当前目录下面去搜索,也不会从源文件相对目录下面去搜索。
  11. - GOPATH可以包含多个路径,**中间用冒号(:)隔开**,就像PATH一样。
  12. 鉴于此,建议golang项目必须严格按照规范的目录结构组织,哪怕是前面这种自包含的项目。
  13. <a name="cdnv4"></a>
  14. # 例子3:vendor目录的使用
  15. 基本规则:
  16. - 使用vendor,项目必须严格按照规范的目录结构组织。
  17. - 即使像例子1中自包含的项目也不能使用vendor
  18. - vender需要在原文件下面创建vendor目录,然后把vendor的文件包放入vendor目录即可,在引用的时候不需要指定vendor路径。
  19. <a name="m7WLY"></a>
  20. # 例子4:vendor和GOPATH谁优先使用
  21. 如果一个包在vendorGOPATH下面都存在那么谁会优先使用呢。<br />结论是:
  22. 1. 优先使用vendor目录下面的包。
  23. 1. 如果vendor下面没有搜索到,再搜索GOPATH下面的包。
  24. 1. 要么完整使用vendor下面的包,要么完整使用GOPATH下面的包,不会混合使用:
  25. 1. 假如一个函数定义再GOPATH下面的包里,而没有定义在vendor路径下的同名包里,那么调用者就会报函数未定义错误,因为调用者如果找到有vendor路径下面的包,就不会去找GOPATH下面的包了。
  26. <a name="wQPfg"></a>
  27. # 例子5:vendor的层次搜索
  28. 前面提到GOPATHPATH类似,可以包含多个路径,中间用分号隔开,go在搜索包的时候会按手续从前往后搜搜。那么vendor怎么处理层级关系呢。<br />规则是:
  29. - 从引用文件所在的vendor路径下面搜索。
  30. - 如果没有找到,那么从上层目录的vendor路径下面搜索。
  31. - 直到srcvendor路径下面搜索。
  32. <a name="r4nEB"></a>
  33. # 总结
  34. 1. 建议golang项目严格按照golang项目组织方式,即使只是一个自包含的项目。
  35. ```bash
  36. <goproject>
  37. |-- src
  38. |-- mainpackage
  39. |-- XXX.go
  40. |-- YYY.go
  41. |-- vendor
  42. |-- deppackage1
  43. |-- XXX1.go
  44. |-- YYY1.go
  45. |-- vendor
  46. |-- deppackage2
  47. |-- XXX2.go
  48. |-- YYY2.go
  49. |-- vendor
  50. |-- VVV1.go
  51. |-- VVV2.go
  52. |-- vendor
  1. GOPATH使用分号(:)隔开的多个路径。
    go编译的时候会从GOPATH/src目录下面搜索import的包。
  2. vender目录放在源文件目录同级,下面包含各个包。

    1. vendor的搜索优先于GOPATH的搜索。
    2. vendor按照路径深度向外按顺序搜索,直到$GOPATH/src/vendor为止。

      相关链接

  3. golang的 GOPATH和vendor的搜索关系