写了一个好用的 Go 包,想分享给别人?本文带你从零了解 Go 模块的创建、发布和引用方式。
一、什么是 Go 模块?
在 Go 中有两个容易混淆的概念:模块(Module) 和 包(Package)。
| 概念 | 定义位置 | 作用 |
|---|---|---|
| 模块 (Module) | go.mod 中的 module xxx |
整个项目的唯一标识,导入路径的起点 |
| 包 (Package) | .go 文件顶部的 package xxx |
代码组织单元,一个模块可以包含多个包 |
简单理解:模块是小区名,包是楼号。别人找你的代码,先找小区(模块),再找楼(包)。
二、创建一个可分享的模块
2.1 项目结构
bash
gotest/
├── go.mod # 模块定义
├── main.go # 主程序(可选)
└── mathutil/ # 一个可被外部使用的包
└── mathutil.go
2.2 go.mod ------ 模块的身份证
go
module gotest
go 1.26.1
module gotest 声明了模块名。模块名是所有包导入路径的前缀。
2.3 编写一个包
mathutil/mathutil.go:
go
package mathutil
// Add 返回两个整数的和
func Add(a, b int) int {
return a + b
}
2.4 在主程序中使用
main.go:
go
package main
import (
"fmt"
"gotest/mathutil" // 模块名/包名
)
func main() {
result := mathutil.Add(10, 20)
fmt.Println("10 + 20 =", result) // 输出: 10 + 20 = 30
}
导入路径的规则:模块名 + "/" + 包的目录路径。
三、把模块分享给别人
方式一:发布到 GitHub(推荐)
这是 Go 社区的标准做法。Go 的模块名天然就是一个网络地址。
步骤 1:使用 GitHub 路径作为模块名
将 go.mod 中的模块名改为你的 GitHub 仓库路径:
go
module github.com/yourname/gotest
go 1.26.1
同时更新所有 import 路径:
go
import "github.com/yourname/gotest/mathutil"
步骤 2:推送到 GitHub
bash
git init
git add .
git commit -m "初始提交"
git remote add origin https://github.com/yourname/gotest.git
git push -u origin main
# 打上版本标签(推荐语义化版本)
git tag v1.0.0
git push --tags
步骤 3:别人使用你的包
别人只需要两步:
bash
# 1. 下载你的包
go get github.com/yourname/gotest/mathutil
go
// 2. 在代码中导入
package main
import (
"fmt"
"github.com/yourname/gotest/mathutil"
)
func main() {
fmt.Println(mathutil.Add(3, 5)) // 输出: 8
}
Go 会根据模块名自动从 GitHub 下载代码。这就是为什么 Go 社区约定用 github.com/xxx 作为模块名 ------ 导入路径和下载地址合二为一。
方式二:本地引用(不发布)
如果只是把源码拷给朋友,不想发到网上,可以用 replace 指令。
目录结构
go
workspace/
├── gotest/ # 你分享的源码
│ ├── go.mod
│ └── mathutil/
│ └── mathutil.go
└── friend-project/ # 朋友自己的项目
├── go.mod
└── main.go
朋友的 go.mod
go
module friend-project
go 1.26.1
require gotest v0.0.0
// 关键:用 replace 将模块名映射到本地路径
replace gotest => ../gotest
replace 告诉 Go:"别去网上找 gotest 这个模块了,它就在旁边的文件夹里。"
朋友的 main.go
go
package main
import (
"fmt"
"gotest/mathutil"
)
func main() {
fmt.Println(mathutil.Add(3, 5)) // 输出: 8
}
四、两种方式对比
| GitHub 发布 | 本地 replace | |
|---|---|---|
| 适合场景 | 开源项目、团队协作 | 私下分享、离线使用 |
| 别人如何获取 | go get github.com/xxx |
手动拷贝源码 |
| 版本管理 | Git Tag(v1.0.0) |
无版本管理 |
| 是否需要网络 | 首次下载需要 | 不需要 |
| 推荐程度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
五、常见问题
Q: 模块名必须是 GitHub 地址吗?
不是必须的。模块名可以是任意字符串(比如 gotest、myapp)。但如果你要发布到网上让别人用,就需要用真实的仓库地址(如 github.com/yourname/gotest),这样 go get 才知道去哪里下载。
Q: 别人能只用我的某个包吗?
可以。Go 的导入粒度是包级别的。别人可以只导入 github.com/yourname/gotest/mathutil,不需要导入整个模块。
总结
- 用
go mod init创建模块 - 在子目录中创建包,函数名大写开头才能被外部使用
- 发布到 GitHub,别人一行
go get就能用 - 不想发布?用
replace指向本地路径
Go 的模块系统设计哲学:导入路径即下载地址。