如何分享自己写的 Go 包

22 阅读3分钟

写了一个好用的 Go 包,想分享给别人?本文带你从零了解 Go 模块的创建、发布和引用方式。

一、什么是 Go 模块?

在 Go 中有两个容易混淆的概念:模块(Module)包(Package)

概念定义位置作用
模块 (Module)go.mod 中的 module xxx整个项目的唯一标识,导入路径的起点
包 (Package).go 文件顶部的 package xxx代码组织单元,一个模块可以包含多个包

简单理解:模块是小区名,包是楼号。别人找你的代码,先找小区(模块),再找楼(包)。


二、创建一个可分享的模块

2.1 项目结构

gotest/
├── go.mod                 # 模块定义
├── main.go                # 主程序(可选)
└── mathutil/              # 一个可被外部使用的包
    └── mathutil.go

2.2 go.mod —— 模块的身份证

module gotest

go 1.26.1

module gotest 声明了模块名。模块名是所有包导入路径的前缀。

2.3 编写一个包

mathutil/mathutil.go

package mathutil

// Add 返回两个整数的和
func Add(a, b int) int {
    return a + b
}

2.4 在主程序中使用

main.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 仓库路径:

module github.com/yourname/gotest

go 1.26.1

同时更新所有 import 路径:

import "github.com/yourname/gotest/mathutil"

步骤 2:推送到 GitHub

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:别人使用你的包

别人只需要两步:

# 1. 下载你的包
go get github.com/yourname/gotest/mathutil
// 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 指令。

目录结构

workspace/
├── gotest/                # 你分享的源码
│   ├── go.mod
│   └── mathutil/
│       └── mathutil.go
└── friend-project/        # 朋友自己的项目
    ├── go.mod
    └── main.go

朋友的 go.mod

module friend-project

go 1.26.1

require gotest v0.0.0

// 关键:用 replace 将模块名映射到本地路径
replace gotest => ../gotest

replace 告诉 Go:"别去网上找 gotest 这个模块了,它就在旁边的文件夹里。"

朋友的 main.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 地址吗?

不是必须的。模块名可以是任意字符串(比如 gotestmyapp)。但如果你要发布到网上让别人用,就需要用真实的仓库地址(如 github.com/yourname/gotest),这样 go get 才知道去哪里下载。

Q: 别人能只用我的某个包吗?

可以。Go 的导入粒度是包级别的。别人可以只导入 github.com/yourname/gotest/mathutil,不需要导入整个模块。

总结

  1. go mod init 创建模块
  2. 在子目录中创建包,函数名大写开头才能被外部使用
  3. 发布到 GitHub,别人一行 go get 就能用
  4. 不想发布?用 replace 指向本地路径

Go 的模块系统设计哲学:导入路径即下载地址