文章目录
前言
Go的工程管理。
一、问题
- 不知道如何同时编译并运行多个Go文件
- 因为Go的语法规范,模块、目录、文件、包、导入包和导入函数不知道怎样命名和书写
- 因为Go的改进,不用传统配置GOPATH方式而是使用Go mod进行工程管理,但不知道怎样使用Go mod
- 目前关于Go工程管理的网上资料较少,使用GOPATH方式的多,总结Go mod方式的少
二、测试环境
- Windows
注意:Windows下的cmd和PowerShell命令行无法识别部分字符,所以不能执行部分Linux下可以执行的命令
-
VS Code
-
开启Go mod机制,命令行执行:
go env -w GO111MODULE=on
# 开启Go mod机制
go env
# 查看GO111MODULE变量是否开启
三、同模块同目录同包
1.目录结构
目录dir:
- 文件a.go
- 文件b.go
2.操作
(1)编写文件b.go:
package main
import "fmt"
// 同包中,函数名首字母无需大写指定公有访问权限
func test() {
fmt.Println(10)
}
(2)编写文件a.go:
package main
// 同包中,无需导入路径
func main() {
test()
// 同包中,可直接调用相应函数
}
(3)命令行执行:
cd dir
# 方式一
go run a.go b.go
# VS Code会在a.go报错找不到test()函数,但能够成功运行
# 方式二
go run .
# 报错:go: go.mod file not found in current directory or any parent directory; see 'go help modules'
go mod init modu
# 通过创建mod文件,使得a.go能够找到依赖项b.go,所以能够运行
# VS Code不再报错,因为通过.mod文件让a.go找到其依赖项b.go
go run .
在生成mod文件后,若在文件go.mod报错:gopls was not able to find modules in your workspace…,参见:关于VS code报错 gopls requires a module at the root of your workspace - 简书 (jianshu.com)
3.总结
- 同模块:使用“go mod init”初始化一个模块,模块名为modu
- 同目录:多go文件在同一目录下,目录名为dir
- 同包:多go文件在同包,包名为main
- 文件名为a.go,b.go,没有特别命名
- 函数名为test,同包中,函数名首字母无需大写指定公有访问权限,无需导入路径,可直接调用相应函数
四、同模块不同目录不同包
1.目录结构
目录dir:
- 文件a.go
- 目录dir_b
目录dir_b:
- 文件b.go
2.操作
(1)编写文件b.go:
package pkg_b
import "fmt"
// 不同包中,函数名首字母需大写指定公有访问权限
func Test() {
fmt.Println(10)
}
(2)命令行执行:
cd dir
go mod init modu
(3)编写文件a.go:
package main
import "modu/dir_b"
// 格式:当前模块名/目录名
// 实际上,import是导入路径,而不是导入包名。所以是dir_b而不是pkg_b
// 奇怪的引用方式,应该把包名命名为目录名才能统一,不过一般同一目录下是同一个包,命名相同。这里为了突显导入格式,目录名和包名命名不同
func main() {
pkg_b.Test()
// 使用函数需要用包名引用
}
(4)命令行执行:
cd dir
# 方式一
go run .
# 方式二
go run a.go
3.总结
- 同模块:使用“go mod init”初始化一个模块,模块名为modu
- 不同目录:多go文件在不同一目录下,目录名为dir和dir_b
- 不同包:多go文件在不同包,包名为main和pkg_b
- 文件名为a.go,b.go,没有特别命名
- 函数名为Test,不同包中,函数名首字母需大写指定公有访问权限
- 导入依赖包->路径的形式:import 当前模块名/目录名
- 使用依赖函数的形式:包名.函数名()
五、不同模块不同目录不同包1
1.目录结构
目录dir:
- 文件a.go
- 目录dir_b
目录dir_b:
- 文件b.go
2.操作
(1)编写文件b.go:
package pkg_b
import "fmt"
// 不同包中,函数名首字母需大写指定公有访问权限
func Test() {
fmt.Println(10)
}
(2)命令行执行:
cd dir_b
go mod init modu_b
(3)编写a.go
package main
import "modu_b"
// 需要用的模块名
func main() {
pkg_b.Test()
// 使用函数需要用包名引用
}
(4)命令行执行:
cd dir
go mod init modu
(5)修改dir下的go.mod文件:
module modu
go 1.20
require modu_b v0.0.0
// 需要用的模块名,版本
replace modu_b => C:\Users\DSHH\Desktop\go_test\dir\dir_b
// 指定查找路径
// 导入该模块实际上是导入该路径
(5)命令行执行:
cd dir
# 方式一
go run .
# 方式二
go run a.go
3.总结
- 不同模块:使用“go mod init”初始化多个模块,模块名为modu和modu_b
- 不同目录:多go文件在不同一目录下,目录名为dir和dir_b
- 不同包:多go文件在不同包,包名为main和pkg_b
- 文件名为a.go,b.go,没有特别命名
- 函数名为Test,不同包中,函数名首字母需大写指定公有访问权限,使用函数需要用包名引用
- 导入依赖模块->路径的形式:import 模块名
- 使用依赖函数的形式:包名.函数名()
六、不同模块不同目录不同包2
1.目录结构
目录dir:
- 目录dir_a
- 目录dir_b
目录dir_a:
- 文件a.go
目录dir_b:
- 文件b.go
2.操作
(1)编写文件b.go:
package pkg_b
import "fmt"
// 不同包中,函数名首字母需大写指定公有访问权限
func Test() {
fmt.Println(10)
}
(2)命令行执行:
cd dir_b
go mod init modu_b
(3)编写a.go
package main
import "modu_b"
// 需要用的模块名
func main() {
pkg_b.Test()
// 使用函数需要用包名引用
}
(4)命令行执行:
cd dir_a
go mod init modu_a
(5)修改dir_a下的go.mod文件:
module modu_a
go 1.20
require modu_b v0.0.0
// 需要用的模块名,版本
replace modu_b => C:\Users\DSHH\Desktop\go_test\dir\dir_b
// 指定查找路径
// 导入该模块实际上是导入该路径
(5)命令行执行:
cd dir_a
# 方式一
go run .
# 方式二
go run a.go
3.总结
- 不同模块:使用“go mod init”初始化多个模块,模块名为modu_a和modu_b
- 不同目录:多go文件在不同一目录下,目录名为dir_a和dir_b
- 不同包:多go文件在不同包,包名为main和pkg_b
- 文件名为a.go,b.go,没有特别命名
- 函数名为Test,不同包中,函数名首字母需大写指定公有访问权限,使用函数需要用包名引用
- 导入依赖模块->路径的形式:import 模块名
- 使用依赖函数的形式:包名.函数名()
七、总结
方式的选择:
-
不使用旧的设置GOPATH变量方式,多文件编程不一定放在src目录下
-
原因:应该是引入新的Go mod模块机制替代了
-
建议使用新的方式,无需每次工程都要配置修改环境变量
使用Go mod方式的建议:
- 一个目录下的所有go文件都是同一个包,目录名和包名相同
- 运行同一个目录下的多个go文件(同个包),使用方式三
- 由第一点:“一个目录下的所有go文件都是同一个包”,方式四的使用并不常见,也容易混乱
- 运行不同目录下,目录有嵌套关系的多个go文件,使用方式五
- 运行不同目录下,目录是并列关系的多个go文件,使用方式六
实际上方式五和六的操作一样
总结
Go的工程管理。
参考资料
- go mod使用 | 全网最详细 - 知乎 (zhihu.com)
- go mod怎么引用同一个项目下面的子目录 - SegmentFault 思否
- Golang1.14 go modules 怎么导入本地其它项目的包? 看完这篇文章, 终于搞懂了_golang 本地引用其它项目包_普通Gopher的博客-CSDN博客
作者的话
- 感谢参考资料的作者/博主
- 作者:夜悊
- 版权所有,转载请注明出处,谢谢~
- 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
- 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
- 文章在认识上有错误的地方, 敬请批评指正
- 望读者们都能有所收获