Appearance
第 14 章:包与模块化
14.1 什么是包?包的作用
包是 Go 语言中代码组织的基本单位,它的主要作用是:
- 组织代码,提高代码的可维护性
- 避免命名冲突
- 实现代码复用
- 控制代码的可见性
14.2 自定义包与导入
创建自定义包
- 创建包目录:在 GOPATH/src 下创建一个目录,目录名就是包名
- 编写包代码:在目录中创建 .go 文件,文件中的包声明必须与目录名一致
- 导出函数/变量:首字母大写的函数和变量是可导出的(公有的)
示例:创建一个数学包
1. 创建包目录
GOPATH/src/mymath/2. 创建包文件 mymath.go
go
package mymath
// Add 加法函数(可导出)
func Add(a, b int) int {
return a + b
}
// Subtract 减法函数(可导出)
func Subtract(a, b int) int {
return a - b
}
// multiply 乘法函数(不可导出)
func multiply(a, b int) int {
return a * b
}导入包
go
import (
"fmt"
"mymath"
)
func main() {
fmt.Println(mymath.Add(3, 5)) // 输出 8
fmt.Println(mymath.Subtract(10, 4)) // 输出 6
// fmt.Println(mymath.multiply(2, 3)) // 错误:不可导出
}导入别名
go
import (
"fmt"
m "mymath" // 使用别名
)
func main() {
fmt.Println(m.Add(3, 5)) // 使用别名调用
}14.3 Go Modules 项目管理(必备)
Go Modules 是 Go 1.11+ 引入的依赖管理工具,用于管理项目依赖。
初始化模块
bash
go mod init github.com/username/projectname依赖管理
- 添加依赖:
go get github.com/gin-gonic/gin - 更新依赖:
go get -u github.com/gin-gonic/gin - 移除未使用的依赖:
go mod tidy - 查看依赖:
go list -m all
go.mod 文件
go
module github.com/username/projectname
go 1.20
require (
github.com/gin-gonic/gin v1.9.0
)14.4 公有与私有(大小写权限)
Go 语言通过标识符的大小写来控制可见性:
- 大写字母开头:公有的,可以被其他包访问
- 小写字母开头:私有的,只能在当前包内访问
示例
go
// 公有变量
var PublicVar = "public"
// 私有变量
var privateVar = "private"
// 公有函数
func PublicFunction() {
// ...
}
// 私有函数
func privateFunction() {
// ...
}
// 公有结构体
type PublicStruct struct {
PublicField string // 公有字段
privateField string // 私有字段
}14.5 项目目录结构规范
标准目录结构
project/
├── cmd/ # 命令行工具
│ └── main.go # 主入口
├── internal/ # 内部包
│ ├── config/ # 配置
│ └── utils/ # 工具函数
├── pkg/ # 可导出的包
│ └── mypackage/ # 自定义包
├── api/ # API 相关
├── configs/ # 配置文件
├── scripts/ # 脚本
├── tests/ # 测试
├── go.mod # Go 模块文件
└── go.sum # 依赖校验文件最佳实践
- 使用清晰的目录结构:根据功能组织代码
- 遵循命名约定:包名使用小写,简短且有描述性
- 避免循环依赖:确保包之间没有循环依赖
- 使用 Go Modules:管理项目依赖
- 合理使用内部包:将不对外暴露的代码放在 internal 目录
示例:一个完整的项目结构
gopher/
├── cmd/
│ └── gopher/
│ └── main.go
├── internal/
│ ├── config/
│ │ └── config.go
│ └── handler/
│ └── handler.go
├── pkg/
│ └── utils/
│ └── utils.go
├── api/
│ └── api.go
├── configs/
│ └── config.yaml
├── go.mod
└── go.sum