Golang中如何设置版本号

Golang中如何设置版本号 在 https://golangbyexample.com/packages-modules-go-second/ 中,作者讨论了 从本地不同模块导入包。这里的基本内容是:

创建如下的目录树:

.
├── math
│   ├── go.mod
│   └── math.go
└── school
    ├── go.mod
    └── school.go

在 math 目录中运行 go mod init sample.com/math

在 school 目录中运行 go mod init school

math.go 文件应如下所示:

package math

func Add(a, b int) int {

return a + b

}

school.go 文件应如下所示:

package main

import (

"fmt"

"sample.com/math"

)

func main() {

fmt.Println(math.Add(2, 4))

}

school/go.mod 文件应如下所示:

module school

go 1.13

replace sample.com/math => ../math

在 school 目录中运行 go run school.go

现在你会看到 school/go.mod 被更改为:

module school

go 1.13

replace sample.com/math => ../math

require sample.com/math v0.0.0-00010101000000-000000000000 // indirect

困扰我的是,无论是 school 还是 math 都没有处于任何版本控制之下(两者都在我的本地机器上)。那么,它是从哪里得到这个版本号的。

  1. 如何设置在 go.mod 文件中显示的版本号(在本例中是 v0.0.0-00010101000000-000000000000)?
  2. 如何在本地从不同模块导入不同版本的包?

更多关于Golang中如何设置版本号的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

你好,

抱歉回复晚了,我刚刚才看到你的问题。希望你已经自己解决了,但如果你还没有,并且为了其他读者的利益,我在这里简单说几句。

第一个问题的答案很简单——如果一个包没有版本,Go 命令会为该包分配一个伪版本

如果 sample.com/math 包在你的控制之下,你可以通过使用一个合适的 SemVer 版本字符串标记仓库来添加版本。否则,你需要请求包的所有者相应地标记他们的包。

我不确定是否正确理解了第二个问题,但当你使用 replace 指令时,你是将 Go 编译器指向你磁盘上的代码。要选择该代码的不同版本,你需要检出带有期望版本标签的代码。

// 示例代码:replace 指令的用法
replace example.com/old/pkg v1.2.3 => ./local/pkg

更多关于Golang中如何设置版本号的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go模块系统中,版本号由版本控制系统(如Git)的标签决定。对于本地模块,可以通过以下方式设置版本号:

1. 为本地模块设置版本号

方法一:使用Git标签(推荐)

# 进入math目录
cd math

# 初始化Git仓库(如果尚未初始化)
git init
git add .
git commit -m "Initial commit"

# 创建版本标签
git tag v1.0.0

# 更新school/go.mod中的replace指令
# school/go.mod
module school

go 1.13

replace sample.com/math => ../math v1.0.0

方法二:使用伪版本号(自动生成)

当模块没有版本标签时,Go会自动生成伪版本号。格式为:

v0.0.0-yyyymmddhhmmss-abcdefabcdef

其中:

  • yyyymmddhhmmss:提交时间戳
  • abcdefabcdef:提交哈希的前12位

2. 在本地导入不同版本的包

场景:math模块有v1.0.0和v2.0.0两个版本

# 目录结构
.
├── math-v1
│   ├── go.mod    # module sample.com/math v1.0.0
│   └── math.go
├── math-v2
│   ├── go.mod    # module sample.com/math/v2 v2.0.0
│   └── math.go
└── school
    ├── go.mod
    └── school.go

math-v1/math.go

package math

func Add(a, b int) int {
    return a + b
}

math-v2/math.go

package math

import "fmt"

func Add(a, b int) int {
    fmt.Println("Using v2.0.0")
    return a + b + 10  // v2版本有不同实现
}

school/go.mod - 同时导入两个版本

module school

go 1.13

replace sample.com/math => ../math-v1
replace sample.com/math/v2 => ../math-v2

require (
    sample.com/math v1.0.0
    sample.com/math/v2 v2.0.0
)

school/school.go - 使用不同版本

package main

import (
    "fmt"
    mathv1 "sample.com/math"
    mathv2 "sample.com/math/v2"
)

func main() {
    // 使用v1版本
    result1 := mathv1.Add(2, 4)
    fmt.Printf("v1 result: %d\n", result1)  // 输出: 6
    
    // 使用v2版本
    result2 := mathv2.Add(2, 4)
    fmt.Printf("v2 result: %d\n", result2)  // 输出: 16 (2+4+10)
}

为v2模块创建正确的go.mod

// math-v2/go.mod
module sample.com/math/v2

go 1.13

3. 手动指定版本号

如果需要固定特定的伪版本号,可以直接在go.mod中指定:

// school/go.mod
module school

go 1.13

replace sample.com/math => ../math v0.0.0-20230115000000-abc123def456

require sample.com/math v0.0.0-20230115000000-abc123def456

4. 查看和修改版本号

# 查看当前依赖的版本
go list -m all

# 修改依赖版本
go mod edit -require=sample.com/math@v1.2.0

# 或者直接编辑go.mod文件

关键点总结:

  1. 版本号来源:来自Git标签(如v1.0.0)或自动生成的伪版本号
  2. 本地模块版本控制:通过Git标签管理版本
  3. 多版本导入:使用模块路径版本后缀(如/v2)区分不同主版本
  4. replace指令:用于将模块路径重定向到本地目录,可以指定版本号

本地开发时,replace指令配合Git标签是管理版本的最有效方式。当模块发布到仓库时,Go工具链会自动从仓库获取正确的版本。

回到顶部