相信很多刚学go的同学都被这几个搞得一头雾水,我也是。。。现在理解了之后写下这篇文章,如果有什么不正确的地方希望能够指出一定改正哈哈哈…
详解当项目中有 go.mod 时,使用 go modules 管理,反之使用 旧的 GOPATH 和 vendor机制。这里针对的是含go.mod的项目
package、import、go.mod1.package
是Go中用于包声明语句的关键字。如果是命令源码文件的话必须是main
,但如果不是的话可以随便取,但是最好最好最好是和目录名一致! 这样方便定位以及使用
关于package的最佳实践:
package is folder.
package name is folder name.
package path is folder path.
2 . import
引入的私有包的名字可以随意取(因为可以用replace代替,后面会讲),但是最好和引入包的目录名字相同,方便定位以及使用。引入公共包时,必须 要类似 github.com/yourname/xxx
,gitee.com/yourname/xxx
这种,否则编译的时候会找不到包!
3 . 被引入的其他项目的包,必须要存在 go.mod
文件,否则编译时会提示
go: proj666@v0.0.0: parsing ..\..\proj2\go.mod: open c:\go_work\github.com\xxx\proj2\go.mod: The system cannot find the file specified.
为什么必须要go.mod
文件呢?
因为你引入的这个包,可能还引入了其他的包,而这些被引入的其他的包及其版本信息都会记录在go.mod
中,这样在编译时就能通过这个go.mod
来拉取其他被引用的包。这个错误提示同时说明了,在引入包前会去读取这个包的go.mod文件
4 . 之前没有 go modules
时,import
可以使用相对路径,例如
import (
"./vendor"
)
这样写之后 编译时 会去 $GOPATH/src
中查找文件。
如果在含有go.mod
不允许使用相对路径!!!
5 . 生成go.mod
的命令如下
go mod init xxx
xxx是模块的命名,xxx就是我们说的项目依赖路径,通常来说该地址就是项目的仓库地址,所有需要引用项目包的地址都填写这个地址,无论是内部之间引用还是外部引用。
也即是说,在项目 启用了 go modules 之后,引用包必须跟 go mod 文件第一行包名一样,
举个特别点的例子
假设现在 两个文件 go1.go , go2.go 在 project 根目录下
go1.go 和 go2.go 的 package 都应当是 main
这个时候加入go1.go想引入 go2.go中的good()函数,只需要
直接 good() 即可 (这其实就相当于他们都在同一个类里,只不过不同的方法)
在编译时,一定要记得是 go build *.go 否则会提示
command-line-arguments
.\go1.go:10:2: undefined: good
第二种:被引入.go文件和引入.go文件处于同一项目不同目录下
假设现在 两个文件 go1.go 在 project/logs 目录下 , go2.go 在 project/utils 目录下
这个时候假如go1.go想引入 go2.go中的Good()函数,只需要
import "project的模块名加目标package名 例如 github.com/xxx/project/utils"
//最后直接引用即可
utils.Good()
导入这个包的地方是 模块内的绝对路径,就是要从go.mod所在的目录开始。
第三种:被引入.go文件和引入.go文件处于不同项目假设现在 两个文件 go1.go 在 project1 目录下 , go2.go 在 project2 目录下
这个时候加入go1.go想引入 go2.go中的Good()函数,只需要
import "project2"
然后在 project1的 go.mod 中添加
require project2 v.0.0.0
replace project2 => c:/project2
//最后直接引用即可
project2.Good()