【Golang实战】实现一个简单的版本比对算法

前段时间与团队成员做了一个线上规则库版本管理后台,用以在客户端在线升级规则库。

规则库的升级方式,其实就是比对规则库版本信息,将当前版本规则库,升级到更新的规则库版本。

在上周发版测试中,发现规则库升级一直报异常,虽然最后排查到问题是出在规则库管理流程上,即线上管理后台并没有上传相关版本的规则库,
但我觉得仍有必要以自己的理解及认识,去重新实现这个版本比对工具。

以下是 golang 的代码实现,并附上测试用例

// CompareVersion compare oldv and newv, if oldv > newv return 1
// if oldv < newv return -1, otherwise return 0, and return -999 if
// version is bad format
func CompareVersion(oldv, newv string) int {
	if strings.Compare(oldv, newv) == 0 {
		return 0
	}
	var (
		oldvs = strings.Split(oldv, ".")
		newvs = strings.Split(newv, ".")

		appendEle = func(t *[]string, c int) {
			for i := 0; i < c; i++ {
				*t = append(*t, "0")
			}
		}
	)

	// if len(oldvs) not equal len(newvs), then make up "0" for the short
	if len(oldvs) >= len(newvs) {
		appendEle(&newvs, len(oldvs) - len(newvs))
	} else {
		appendEle(&oldvs, len(newvs) - len(oldvs))
	}

	// compare first element, if not equal, then return ret, or continue compare
	var firstCompareResult = strings.Compare(oldvs[0], newvs[0])
	if firstCompareResult != 0 {
		return firstCompareResult
	}

	// compare the other element
	for i := 1; i <= len(newvs)-1; i++ {
		var (
			err error
			ov, nv int
		)
		ov, err = strconv.Atoi(oldvs[i])
		if err != nil {
			log.Printf("Bad format %+v \n", oldvs[i])
			return -999
		}
		nv, err = strconv.Atoi(newvs[i])
		if err != nil {
			log.Printf("Bad format %+v \n", newvs[i])
			return -999
		}
		if ov == nv {
			continue
		} else if ov > nv {
			return 1
		} else {
			return -1
		}
	}
	return 0
}

测试用例及测试结果

func TestCompareVersion(t *testing.T) {
	var versionTestSlice = [][]string{
		{">", "2.2.1", "2.2.0"},
		{">", "2.2.1", "2.1.9"},
		{"=", "2.2.1", "2.2.01"},
		{">", "2.2", "2.1.1"},
		{"<", "2.2", "2.2.1"},
		{"<", "2.2.3.1", "2.2.3.5"},
		{">", "2.2.3.1", "2.2.3.0"},
		{"<", "2.2.3.4", "2.2.4.4.5"},
		{"<", "2.2.3.4.5.6", "2.2.3.4.5.12"},
		{">", "2.2.3.4.5.6", "2.2.2.4.5.12"},
		{">", "3.0.0.1", "3.0.0.0.1"},
		{">", "v2.2.1", "v2.2.0"},
		{">", "v2.2.1", "v2.1.9"},
		{"=", "v2.2.1", "v2.2.01"},
		{">", "v2.2", "v2.1.1"},
		{"<", "v2.2", "v2.2.1"},
		{"<", "v2.2.3.1", "v2.2.3.5"},
		{">", "v3.0.1", "v2.3.5"},
		{"=", "3.1", "3.1."},
	}
	for _, v := range versionTestSlice {
		t.Logf("Expect %s %s %s -> %d", v[1], v[0], v[2], CompareVersion(v[1], v[2]))
	}
}

输出如下:

❯ go test -v .\compare_version_test.go .\compare_version.go
=== RUN   TestCompareVersion
2020/06/18 15:44:44 Bad format
--- PASS: TestCompareVersion (0.02s)
    compare_version_test.go:28: Expect 2.2.1 > 2.2.0 -> 1
    compare_version_test.go:28: Expect 2.2.1 > 2.1.9 -> 1
    compare_version_test.go:28: Expect 2.2.1 = 2.2.01 -> 0
    compare_version_test.go:28: Expect 2.2 > 2.1.1 -> 1
    compare_version_test.go:28: Expect 2.2 < 2.2.1 -> -1
    compare_version_test.go:28: Expect 2.2.3.1 < 2.2.3.5 -> -1
    compare_version_test.go:28: Expect 2.2.3.1 > 2.2.3.0 -> 1
    compare_version_test.go:28: Expect 2.2.3.4 < 2.2.4.4.5 -> -1
    compare_version_test.go:28: Expect 2.2.3.4.5.6 < 2.2.3.4.5.12 -> -1
    compare_version_test.go:28: Expect 2.2.3.4.5.6 > 2.2.2.4.5.12 -> 1
    compare_version_test.go:28: Expect 3.0.0.1 > 3.0.0.0.1 -> 1
    compare_version_test.go:28: Expect v2.2.1 > v2.2.0 -> 1
    compare_version_test.go:28: Expect v2.2.1 > v2.1.9 -> 1
    compare_version_test.go:28: Expect v2.2.1 = v2.2.01 -> 0
    compare_version_test.go:28: Expect v2.2 > v2.1.1 -> 1
    compare_version_test.go:28: Expect v2.2 < v2.2.1 -> -1
    compare_version_test.go:28: Expect v2.2.3.1 < v2.2.3.5 -> -1
    compare_version_test.go:28: Expect v3.0.1 > v2.3.5 -> 1
    compare_version_test.go:28: Expect 3.1 = 3.1. -> -999
PASS
ok      command-line-arguments  0.384s
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值