几种Go版本管理工具

缘起:


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

点击查看代码:
package main

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

func main() {

 http.HandleFunc("/register", deal) //设置访问的路由

 fmt.Println("1111:"2222)

 err := http.ListenAndServe(":8088"nil//设置监听的端口
 if err != nil {
  log.Fatal("ListenAndServe: ", err)
 }

}

func deal(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)
)

func crack(text string) string {

 name := []byte(text)
 length := len(name) + 4
 padded := ((-length) & (8 - 1)) + length
 bs := make([]byte4)
 binary.BigEndian.PutUint32(bs, uint32(len(name)))
 buff := bytes.Buffer{}
 buff.Write(bs)
 buff.Write(name)

 var ckName int64 = 0x7a21c951691cd470
 var 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 int64
  if 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 int32
 for _, 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 {
 case 0x0401:
 case 0x0402:
 case 0x0403:
  in |= s
  break
 default:
  in |= 0x01000000 | (s & 0xffffff)
  break
 }

 out := newCkCipher(ckKey).decrypt(in)

 var n2 int64
 for 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
}

func newCkCipher(ckKey int64) ckCipher {
 ck := ckCipher{}

 var ld [2]int32
 ld[0] = int32(ckKey)
 ld[1] = int32(uint64(ckKey) >> 32)

 ck.rk[0] = -1209970333
 for i := 1; i < roundKeys; i++ {
  ck.rk[i] = ck.rk[i-1] + -1640531527
 }
 var a, b int32
 var i, j int

 for 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)
}

func rotateLeft(x int32, y int32) int32 {
 return int32(x<<(y&(32-1))) | int32(uint32(x)>>(32-(y&(32-1))))
}

func rotateRight(x int32, y int32) int32 {
 return int32(uint32(x)>>(y&(32-1))) | int32(x<<(32-(y&(32-1))))
}

func pkLong(a int32, b int32) int64 {
 return (int64(a) & 0xffffffff) | (int64(b) << 32)
}

但到了Linux上,就会报错:

alt
# 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上进行交叉编译[1]:

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

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

也没有什么问题

alt

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

alt
alt

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。具体见原始项目[2]

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

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

安装go 1.11

gvm install go1.11
alt

选择版本

gvm use go1.11
alt

果然已经变为 Go 1.11


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

alt



gvm更多命令


查看版本

➜ gvm list

gvm gos (installed)

=> go1.11
   system

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

点击查看Go所有版本:
 gvm listall

gvm 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,始终是极好的选择

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

alt
alt



其他方案--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

alt

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




其他方案--brew


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

还可以用brew

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

(从1.16开始支持m1)

alt



问题解决


alt

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


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

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

alt


参考:

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




类似的工具还有g[6]

alt

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

参考资料

[1]

交叉编译: https://studygolang.com/articles/14376

[2]

原始项目: https://github.com/moovweb/gvm#mac-os-x-requirements

[3]

此文: https://blog.csdn.net/qq_45534061/article/details/112256901

[4]

这里: https://formulae.brew.sh/formula/go#default

[5]

如何灵活地进行 Go 版本管理: https://juejin.cn/post/6844903949137346573

[6]

g: https://github.com/voidint/g

[7]

gvc: https://github.com/moqsien/gvc

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/117554.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 8 新特性——Lambda 表达式(1)

Lambda 表达式&#xff08;Lambda expression&#xff09;是一个匿名函数&#xff0c;基于数学中的λ演算得名&#xff0c;也可称为闭包&#xff08;Closure&#xff09;。现在很多语言都支持 Lambda 表达式&#xff0c;如 C、C#、Java、 Python 和 JavaScript 等。Lambda 表达…

Gin 框架入门实战系列(一)

GIN介绍 Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点 对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错 借助框架开发,不仅可以省去很多常用的封装带来的时间,…

多线程应用——阻塞队列

阻塞队列 文章目录 阻塞队列1.队列的概念2.阻塞队列3.现实中的例子4.消息队列5.使用队列的优势1.解耦2.削峰填谷3.异步操作 6.实现 1.队列的概念 一种先进先出的数据结构 2.阻塞队列 队列写元素是从队尾插入&#xff0c;从对头取出 当插入元素时&#xff0c;先判断一下队列…

Window10 安装 Lua

1、下载地址&#xff1a;https://luabinaries.sourceforge.net/download.html 2、下载 3、解压后共有4个文件&#xff0c;这里我把这几个文件放到如下目录 D:\Program Files\lua-5.4.2\bin 4、定义环境变量 5、打开 powershell&#xff0c;运行 lua54 -v PS C:\Windows\syste…

企业网络安全:威胁检测和响应 (TDR)

什么是威胁检测和响应 威胁检测和响应&#xff08;TDR&#xff09;是指识别和消除 IT 基础架构中存在的恶意威胁的过程。它涉及主动监控、分析和操作&#xff0c;以降低风险并防止未经授权的访问、恶意活动和数据泄露&#xff0c;以免它们对组织的网络造成任何潜在损害。威胁检…

Dump文件的生成以及使用WinDbg静态分析

前言 本文章主要介绍了如何生成Dump文件&#xff0c;包括两种方式&#xff0c;通过代码生成和通过注册表生成。并且介绍了WinDbg工具的下载和使用&#xff0c;以及如何使用WinDbg工具去静态分析Dump文件&#xff0c;从而找到程序的崩溃位置。 生成Dump文件 通过调用WinAPI生成…

django.core.exceptions.AppRegistryNotReady: Apps aren‘t loaded yet.

运行django测试用例报错django.core.exceptions.AppRegistryNotReady: Apps arent loaded yet. 解决&#xff1a;在测试文件上方加上 django.setup() django.setup()是Django框架中的一个函数。它用于在非Django环境下使用Django的各种功能、模型和设置。 在常规的Django应用…

堆对象数组

C自学精简教程 目录(必读) 之前我们学习了基础类型的堆数组 现在我们来看堆数组的元素是类对象的场景 堆对象数组 堆对象数组的每一个元素都是一个类对象。 使用堆对象数组的语法和使用堆数组的语法是一样的。 #include <iostream> #include <string> using …

ZMTP协议

ZoreMQ Transport Protocol是一个传输层协议&#xff0c;用于ZMQ的连接的信息交互&#xff0c;本文档描述的是3.0协议&#xff0c;主要分析基于NULL Security Mechanism 协议语法 ZMTP由三部分组成&#xff0c;分别是 greeting、handshake、traffic 部分描述构成greeting描述…

移动基站ip的工作原理

原理介绍 Basic Principle 先说一下概念&#xff0c;大家在不使用 WIFI 网络的时候&#xff0c;使用手机通过运营商提供的网络进行上网的时候&#xff0c;目前都是在用户端使用私有IP&#xff0c;然后对外做 NAT 转换&#xff0c;这样的情况就导致大家统一使用一些 IP 段进行访…

Unity中Shader的帧缓存区Clear(color+Z+stencil)

文章目录 前言一、什么是帧缓冲区二、片段运算三、随机扫描显示器&#xff08;可以按照自定义路径绘制帧&#xff09;四、光栅扫描显示器&#xff08;从左到右&#xff0c;从上到下&#xff0c;依次绘制&#xff09;五、缓冲的方式&#xff1a;单缓冲 和 双缓冲1、单缓冲2、双缓…

VBA中如何将if写到一行

在VBA中&#xff0c;可以使用以下两种方式来编写一行if语句&#xff1a; 使用三元运算符&#xff1a; Dim result As String result "Yes" If True Else "No"在这个例子中&#xff0c;如果条件为真&#xff0c;则result变量的值为"Yes"&#…

pycharm 打开Terminal时报错activate.ps1,因为在此系统上禁止运行脚本,并因此无法进入虚拟环境

pycharm 打开Terminal时报错activate.ps1&#xff0c;因为在此系统上禁止运行脚本&#xff0c;并因此无法进入虚拟环境 如下图所示&#xff1a; 网上说可以set_restrictFalse什么的&#xff0c;虽然也可但可能会降低电脑安全性&#xff0c;可以将下面的终端改为cmd.exe即可

SpringCloudAlibaba Gateway(三)-整合Sentinel功能路由维度、API维度进行流控

Gateway整合Sentinel ​ 前面使用过Sentinel组件对服务提供者、服务消费者进行流控、限流等操作。除此之外&#xff0c;Sentinel还支持对Gateway、Zuul等主流网关进行限流。 ​ 自sentinel1.6.0版开始&#xff0c;Sentinel提供了Gateway的适配模块&#xff0c;能针对路由(rou…

Linux centos7 bash编程——-求质数和

训练项目&#xff1a;使用函数求质数和。 定义一个函数IsPrime()&#xff0c;据此判断一个数是否为质数 由用户输入一个整数&#xff0c;求出比此数大的两个最小质数之和。 一、解决思路: 1.先在键盘上输入一个整数 2.求出比此数大的最小质数 3.再求出比此质数大的另一个…

2.3 Vector 动态数组(迭代器)

C数据结构与算法 目录 本文前驱课程 1 C自学精简教程 目录(必读) 2 Vector<T> 动态数组&#xff08;模板语法&#xff09; 本文目标 1 熟悉迭代器设计模式&#xff1b; 2 实现数组的迭代器&#xff1b; 3 基于迭代器的容器遍历&#xff1b; 迭代器语法介绍 对迭…

全民健康生活方式行动日,天猫健康联合三诺生物推出“15天持续测糖计划”

糖尿病是全球高发慢性病中患病人数增长最快的疾病&#xff0c;是导致心血管疾病、失明、肾衰竭以及截肢等重大疾病的主要病因之一。目前中国有近1.4亿成人糖尿病患者&#xff0c;科学的血糖监测和健康管理对于糖尿病患者来说至关重要。 在9月1日全民健康生活方式行动日前夕&am…

如何排查 Flink Checkpoint 失败问题?

分析&回答 这是 Flink 相关工作中最常出现的问题&#xff0c;值得大家搞明白。 1. 先找到超时的subtask序号 图有点问题&#xff0c;因为都是成功没失败的&#xff0c;尴尬了。 借图&#xff1a; 2. 找到对应的机器和任务 方法很多&#xff0c;这里看自己习惯和公司提供…

【网络编程上】

目录 一.什么是互联网 1.计算机网络的定义与分类&#xff08;了解&#xff09; &#xff08;1&#xff09;计算机网络的定义 &#xff08;2&#xff09;计算机网络的分类 ① 按照网络的作用范围进行分类 ②按照网络的使用者进行分类 2.网络的网络 &#xff08;理解&#xf…

探索内网穿透工具:实现局域网SQL Server数据库的公网远程访问方法

文章目录 1.前言2.本地安装和设置SQL Server2.1 SQL Server下载2.2 SQL Server本地连接测试2.3 Cpolar内网穿透的下载和安装2.3 Cpolar内网穿透的注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 数据库的重要性相信大家都有所了解&…