Go的工程管理

前言

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的工程管理。


参考资料


作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值