几种Go版本管理工具

简介: 几种Go版本管理工具

缘起:


编译下面这段代码时,在Mac上没有什么问题,正常运行,

点击查看代码:

go

复制代码

package main

import (
"bytes""encoding/binary""encoding/json""fmt""log""math/rand""net/http""time")funcmain() {

	http.HandleFunc("/register", deal) //设置访问的路由	fmt.Println("1111:", 2222)	err := http.ListenAndServe(":8088", nil) //设置监听的端口if err != nil {		log.Fatal("ListenAndServe: ", err)	}}funcdeal(w http.ResponseWriter, r *http.Request) {

// Golang: 接收GET和POST参数 https://www.cnblogs.com/liuhe688/p/11063945.html// 根据请求body创建一个json解析器实例	decoder := json.NewDecoder(r.Body)// 用于存放参数key=value数据var params map[string]string// 解析参数 存入map	decoder.Decode(&params)	name := params["name"]	rand.Seed(time.Now().UnixNano())	key := crack(name)	fmt.Println("name:", name, "    key:", crack(name))	fmt.Fprintf(w, key) //这个写入到w的是输出到客户端的}const (
	rounds    = 12	roundKeys = 2 * (rounds + 1))funccrack(text string)string {

	name := []byte(text)	length := len(name) + 4	padded := ((-length) & (8 - 1)) + length	bs := make([]byte, 4)	binary.BigEndian.PutUint32(bs, uint32(len(name)))	buff := bytes.Buffer{}	buff.Write(bs)	buff.Write(name)var ckName int64 = 0x7a21c951691cd470var ckKey int64 = -5408575981733630035	ck := newCkCipher(ckName)	outBuff := bytes.Buffer{}for i := 0; i < padded; i += 8 {		bf := buff.Bytes()[i : i+8]		buf := bytes.NewBuffer(bf)var nowVar int64if err := binary.Read(buf, binary.BigEndian, &nowVar); err != nil {panic(err)		}		dd := ck.encrypt(nowVar)		outBuff.WriteByte(byte(dd >> 56))		outBuff.WriteByte(byte(dd >> 48))		outBuff.WriteByte(byte(dd >> 40))		outBuff.WriteByte(byte(dd >> 32))		outBuff.WriteByte(byte(dd >> 24))		outBuff.WriteByte(byte(dd >> 16))		outBuff.WriteByte(byte(dd >> 8))		outBuff.WriteByte(byte(dd))	}var n int32for _, b := range outBuff.Bytes() {		n = rotateLeft(n^int32(int8(b)), 0x3)	}	prefix := n ^ 0x54882f8a	suffix := rand.Int31()	in := int64(prefix) << 32	s := int64(suffix)switch suffix >> 16 {case0x0401:case0x0402:case0x0403:		in |= sbreakdefault:		in |= 0x01000000 | (s & 0xffffff)break	}	out := newCkCipher(ckKey).decrypt(in)var n2 int64for i := 56; i >= 0; i -= 8 {		n2 ^= int64((uint64(in) >> i) & 0xff)	}	vv := int32(n2 & 0xff)if vv < 0 {		vv = -vv	}return fmt.Sprintf("%02x%016x", vv, uint64(out))}type ckCipher struct {
	rk [roundKeys]int32}funcnewCkCipher(ckKey int64) ckCipher {
	ck := ckCipher{}var ld [2]int32	ld[0] = int32(ckKey)	ld[1] = int32(uint64(ckKey) >> 32)	ck.rk[0] = -1209970333for i := 1; i < roundKeys; i++ {		ck.rk[i] = ck.rk[i-1] + -1640531527	}var a, b int32var i, j intfor k := 0; k < 3*roundKeys; k++ {		ck.rk[i] = rotateLeft(ck.rk[i]+(a+b), 3)		a = ck.rk[i]		ld[j] = rotateLeft(ld[j]+(a+b), a+b)		b = ld[j]		i = (i + 1) % roundKeys		j = (j + 1) % 2	}return ck}func(ck ckCipher) encrypt(in int64) int64 {
	a := int32(in) + ck.rk[0]	b := int32(uint64(in)>>32) + ck.rk[1]for r := 1; r <= rounds; r++ {		a = rotateLeft(a^b, b) + ck.rk[2*r]		b = rotateLeft(b^a, a) + ck.rk[2*r+1]	}return pkLong(a, b)}func(ck ckCipher) decrypt(in int64) int64 {
	a := int32(in)	b := int32(uint64(in) >> 32)for i := rounds; i > 0; i-- {		b = rotateRight(b-ck.rk[2*i+1], a) ^ a		a = rotateRight(a-ck.rk[2*i], b) ^ b	}	b -= ck.rk[1]	a -= ck.rk[0]return pkLong(a, b)}funcrotateLeft(x int32, y int32)int32 {
returnint32(x<<(y&(32-1))) | int32(uint32(x)>>(32-(y&(32-1))))}funcrotateRight(x int32, y int32)int32 {
returnint32(uint32(x)>>(y&(32-1))) | int32(x<<(32-(y&(32-1))))}funcpkLong(a int32, b int32)int64 {
return (int64(a) & 0xffffffff) | (int64(b) << 32)}


但到了Linux上,就会报错

微信截图_20230925191347.png

# command-line-arguments
./http_register.go:113:15: invalid operation: uint64(in) >> i (shift count type int, must be unsigned integer)
./http_register.go:175:16: invalid operation: x << (y & (32 - 1)) (shift count type int32, must be unsigned integer)
./http_register.go:175:47: invalid operation: uint32(x) >> (32 - y & (32 - 1)) (shift count type int32, must be unsigned integer)
./http_register.go:179:24: invalid operation: uint32(x) >> (y & (32 - 1)) (shift count type int32, must be unsigned integer)
./http_register.go:179:47: invalid operation: x << (32 - y & (32 - 1)) (shift count type int32, must be unsigned integer)

而在Mac上进行交叉编译:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build 文件名.go

(如果出现GOROOT blabla之类的,执行go env -w GO111MODULE=off )

也没有什么问题

微信截图_20230925191455.png

导致这种情况的原因,可能因Go版本不同而导致

微信截图_20230925191507.png

微信截图_20230925191516.png

Mac上的Go版本为 1.16, 而Linux上Go版本为 1.11




解决:


最初想看一下有没有在线的不同Go版本执行工具,无果而终.

想到之前用php时,用过brew switch来切换不同的php版本.但搜索之后发现,这个命令被 brew 弃用了.


之前用过node版本工具nvm,于是试图找寻Go有没有类似工具,发现了gvm.

安装gvm

$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

N.B. : 不同操作系统还需要安装所需依赖,如Mac需要执行brew install mercurial安装mercurial。具体见原始项目

另外如果出现“ERROR: Unrecognized command line argument: 'use'”报错,可参考此文,执行:

cp -rp .gvm/scripts/env/use .gvm/scripts/use
chmod 775 .gvm/scripts/use

安装go 1.11

gvm install go1.11

微信截图_20230925191713.png

选择版本

gvm use go1.11

微信截图_20230925191757.png

果然已经变为 Go 1.11


在 Go 1.11 环境下执行,果然出现了和在Linux上Go 1.11下出现的同样错误

微信截图_20230925191811.png

gvm更多命令


查看版本

➜ gvm list
gvm gos (installed)
=> go1.11
   system

查看Go的所有版本 (版本来源于源码中的 tag 标签)

点击查看Go所有版本:

go

复制代码

 gvm listallgvm gos (available)   go1   go1.0.1   go1.0.2   go1.0.3   go1.1   go1.1rc2   go1.1rc3   go1.1.1   go1.1.2   go1.2   go1.2rc2   go1.2rc3   go1.2rc4   go1.2rc5   go1.2.1   go1.2.2   go1.3   go1.3beta1   go1.3beta2   go1.3rc1   go1.3rc2   go1.3.1   go1.3.2   go1.3.3   go1.4   go1.4beta1   go1.4rc1   go1.4rc2   go1.4.1   go1.4.2   go1.4.3   go1.5   go1.5beta1   go1.5beta2   go1.5beta3   go1.5rc1   go1.5.1   go1.5.2   go1.5.3   go1.5.4   go1.6   go1.6beta1   go1.6beta2   go1.6rc1   go1.6rc2   go1.6.1   go1.6.2   go1.6.3   go1.6.4   go1.7   go1.7beta1   go1.7beta2   go1.7rc1   go1.7rc2   go1.7rc3   go1.7rc4   go1.7rc5   go1.7rc6   go1.7.1   go1.7.2   go1.7.3   go1.7.4   go1.7.5   go1.7.6   go1.8   go1.8beta1   go1.8beta2   go1.8rc1   go1.8rc2   go1.8rc3   go1.8.1   go1.8.2   go1.8.3   go1.8.4   go1.8.5   go1.8.5rc4   go1.8.5rc5   go1.8.6   go1.8.7   go1.9   go1.9beta1   go1.9beta2   go1.9rc1   go1.9rc2   go1.9.1   go1.9.2   go1.9.3   go1.9.4   go1.9.5   go1.9.6   go1.9.7   go1.10   go1.10beta1   go1.10beta2   go1.10rc1   go1.10rc2   go1.10.1   go1.10.2   go1.10.3   go1.10.4   go1.10.5   go1.10.6   go1.10.7   go1.10.8   go1.11   go1.11beta1   go1.11beta2   go1.11beta3   go1.11rc1   go1.11rc2   go1.11.1   go1.11.2   go1.11.3   go1.11.4   go1.11.5   go1.11.6   go1.11.7   go1.11.8   go1.11.9   go1.11.10   go1.11.11   go1.11.12   go1.11.13   go1.12   go1.12beta1   go1.12beta2   go1.12rc1   go1.12.1   go1.12.2   go1.12.3   go1.12.4   go1.12.5   go1.12.6   go1.12.7   go1.12.8   go1.12.9   go1.12.10   go1.12.11   go1.12.12   go1.12.13   go1.12.14   go1.12.15   go1.12.16   go1.12.17   go1.13   go1.13beta1   go1.13rc1   go1.13rc2   go1.13.1   go1.13.2   go1.13.3   go1.13.4   go1.13.5   go1.13.6   go1.13.7   go1.13.8   go1.13.9   go1.13.10   go1.13.11   go1.13.12   go1.13.13   go1.13.14   go1.13.15   go1.14   go1.14beta1   go1.14rc1   go1.14.1   go1.14.2   go1.14.3   go1.14.4   go1.14.5   go1.14.6   go1.14.7   go1.14.8   go1.14.9   go1.14.10   go1.14.11   go1.14.12   go1.14.13   go1.14.14   go1.14.15   go1.15   go1.15beta1   go1.15rc1   go1.15rc2   go1.15.1   go1.15.2   go1.15.3   go1.15.4   go1.15.5   go1.15.6   go1.15.7   go1.15.8   go1.15.9   go1.15.10   go1.15.11   go1.15.12   go1.16   go1.16beta1   go1.16rc1   go1.16.1   go1.16.2   go1.16.3   go1.16.4   release.r56   release.r57   release.r58   release.r59   release.r60   release.r57.1   release.r57.2   release.r58.1   release.r58.2   release.r60.1   release.r60.2   release.r60.3




其他方案--IDE

不管对于Python,还是Golang,面对版本问题时,使用PyCharm或GoLand,始终是极好的选择

但现在只能下载最近几个版本,更久远的无法安装

微信截图_20230925191914.png

微信截图_20230925191927.png


其他方案--Docker

docker pull golang:1.xx

docker run -it  --name golang-1.xx自定义名称  golang:1.xx

进入到容器中(默认是基于ubuntu的镜像)

(如果没有vi/vim)切换源,安装vim

mv /etc/apt/sources.list /etc/apt/sources.list.bak
echo  "deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free" >/etc/apt/sources.list
echo  "deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free" >>/etc/apt/sources.list
echo  "deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free" >>/etc/apt/sources.list
echo  "deb http://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free" >>/etc/apt/sources.list
apt-get update
apt-get install -y vim

微信截图_20230925192015.png

这种方式是万能的,任何版本都可以得到 (但是都是Linux版本的~)




其他方案--brew


但如果想用Mac的以往版本的Go,用Docker方式做不到~

还可以用brew

可以在这里找到所有可以安装的Go版本

(从1.16开始支持m1)

微信截图_20230925192031.png

问题解决

微信截图_20230925192112.png

切换为Go 1.11.5版本后,IDE会自动报错


y为int32,将其强制转为uint32即可,

i为int,将其强制转为uint即可.

微信截图_20230925192123.png

参考:

如何灵活地进行 Go 版本管理




类似的工具还有g

微信截图_20230925192201.png

某位大佬推荐 gvc, 能管理很多种语言的版本

目录
相关文章
|
4月前
|
SQL 关系型数据库 MySQL
「Go开源」goose:深入学习数据库版本管理工具
「Go开源」goose:深入学习数据库版本管理工具
「Go开源」goose:深入学习数据库版本管理工具
|
Linux Go iOS开发
Go多版本管理工具 - g
`g` 是一个跨平台(Linux、Windows、MacOS)的 go多版本管理工具。
371 0
|
17天前
|
存储 Go 索引
go语言中数组和切片
go语言中数组和切片
27 7
|
17天前
|
Go 开发工具
百炼-千问模型通过openai接口构建assistant 等 go语言
由于阿里百炼平台通义千问大模型没有完善的go语言兼容openapi示例,并且官方答复assistant是不兼容openapi sdk的。 实际使用中发现是能够支持的,所以自己写了一个demo test示例,给大家做一个参考。
|
17天前
|
程序员 Go
go语言中结构体(Struct)
go语言中结构体(Struct)
92 71
|
16天前
|
存储 Go 索引
go语言中的数组(Array)
go语言中的数组(Array)
100 67
|
19天前
|
Go 索引
go语言for遍历数组或切片
go语言for遍历数组或切片
90 62
|
21天前
|
并行计算 安全 Go
Go语言中的并发编程:掌握goroutines和channels####
本文深入探讨了Go语言中并发编程的核心概念——goroutine和channel。不同于传统的线程模型,Go通过轻量级的goroutine和通信机制channel,实现了高效的并发处理。我们将从基础概念开始,逐步深入到实际应用案例,揭示如何在Go语言中优雅地实现并发控制和数据同步。 ####
|
17天前
|
存储 Go
go语言中映射
go语言中映射
32 11
|
19天前
|
Go
go语言for遍历映射(map)
go语言for遍历映射(map)
29 12