1 - goroutine

获取goroutineID

func goID() uint64 {
    b := make([]byte, 64)
    b = b[:runtime.Stack(b, false)]
    b = bytes.TrimPrefix(b, []byte("goroutine "))
    b = b[:bytes.IndexByte(b, ' ')]
    n, _ := strconv.ParseUint(string(b), 10, 64)
    return n
}

2 - Map

初始化

// 先声明map
var m1 map[string]string
// 再使用make函数创建一个非nil的map,nil map不能赋值
m1 = make(map[string]string)
// 最后给已声明的map赋值
m1["a"] = "aa"
m1["b"] = "bb"

// 直接创建
m2 := make(map[string]string)
// 然后赋值
m2["a"] = "aa"
m2["b"] = "bb"

// 初始化 + 赋值一体化
m3 := map[string]string{
    "a": "aa",
    "b": "bb",
}

判断key是否存在

if v, ok := m1["a"]; ok {
    fmt.Println(v)
} else {
    fmt.Println("Key Not Found")
}

遍历map

for k, v := range m1 {
    fmt.Println(k, v)
}

删除一个元素

scene := make(map[string]int)

// 准备map数据
scene["route"] = 66
scene["brazil"] = 4
scene["china"] = 960

delete(scene, "brazil")

for k, v := range scene {
    fmt.Println(k, v)
}
//route 66
//china 960

安全的Map

1. map+锁

type SafeMap struct {
    Data map[string]interface{}
    Lock sync.RWMutex
}
 
func (this *SafeMap) Get(k string) interface{} {
    this.Lock.RLock()
    defer this.Lock.RUnlock()
    if v, exit := this.Data[k]; exit {
        return v
    }
    return nil
}
 
func (this *SafeMap) Set(k string, v interface{}) {
    this.Lock.Lock()
    defer this.Lock.Unlock()
    if this.Data == nil {
        this.Data = make(map[string]interface{})
    }
    this.Data[k] = v
}

2. sync.map

var test sync.Map
 
//设置元素
func set (k,v interface{}){
    test.Store(k,v)
}
 
//获得元素
func get (k interface{}) interface{}{
    tem ,exit := test.Load(k)
    if exit {
        return tem
    }
    return nil
}
 
//传入一个 函数 ,sync.map  会内部迭代 ,运行这个函数
func ranggfunc (funcs func(key, value interface{}) bool) {
    test.Range(funcs)
}
 
//删除元素
func del(key interface{}){
    test.Delete(key)
}

4 - 结构体

判断变量是否==空结构体

if reflect.DeepEqual(deviceModel, models.DeviceModel{}) {
    //code
}

结构提转map

//使用反射转换的效率要高于 struct->json->map
//传变量
func Struct2Map(obj interface{}) map[string]interface{} {
    t := reflect.TypeOf(obj)
    v := reflect.ValueOf(obj)
 
    var data = make(map[string]interface{})
    for i := 0; i < t.NumField(); i++ {
        data[t.Field(i).Name] = v.Field(i).Interface()
    }
    return data
}

//传指针,如果一定要声明称指针( obj := new(Test)或obj := &Test{} )时,Struct2Map方法中需要将取出指针的内容然后继续操作,因为指针是没有Field()方法的。
func Struct2Map(obj interface{}) map[string]interface{} {
    obj_v := reflect.ValueOf(obj)
    v := obj_v.Elem()
    typeOfType := v.Type()
    var data = make(map[string]interface{})
    for i := 0; i < v.NumField(); i++ {
        field := v.Field(i)
        data[typeOfType.Field(i).Name] = field.Interface()
    }
    return data
}
// Clone deep-copies a to b
func Clone(a, b interface{}) {

    buff := new(bytes.Buffer)
    enc := gob.NewEncoder(buff)
    dec := gob.NewDecoder(buff)
    enc.Encode(a)
    dec.Decode(b)
}

func main() {
    a1 := A{
        AA: "jilao",
        BB: 1,
    }
    var a2 A
    Clone(a1, a2)
    a2.AA = "lakjg;odfig"
    fmt.Println(a1.AA)
    fmt.Println(a2.AA)
}

5 - 进制转换

import (
   "fmt"
   "log"
   "math"
   "strconv"
   "strings"
)

// Decimal to binary  十进制转二进制
func DecBin(n int64) string {
   if n < 0 {
      log.Println("Decimal to binary error: the argument must be greater than zero.")
      return ""
   }
   if n == 0 {
      return "0"
   }
   s := ""
   for q := n; q > 0; q = q / 2 {
      m := q % 2
      s = fmt.Sprintf("%v%v", m, s)
   }
   
   return s
}

// Decimal to octal 十进制转八进制
func DecOct(d int64) int64 {
   if d == 0 {
      return 0
   }
   if d < 0 {
      log.Println("Decimal to octal error: the argument must be greater than zero.")
      return -1
   }
   s := ""
   for q := d; q > 0; q = q / 8 {
      m := q % 8
      s = fmt.Sprintf("%v%v", m, s)
   }
   n, err := strconv.Atoi(s)
   if err != nil {
      log.Println("Decimal to octal error:", err.Error())
      return -1
   }
   return int64(n)
}

// Decimal to hexadecimal 十进制转16进制
func DecHex(n int64) string {
   if n < 0 {
      log.Println("Decimal to hexadecimal error: the argument must be greater than zero.")
      return ""
   }
   if n == 0 {
      return "0"
   }
   hex := map[int64]int64{10: 65, 11: 66, 12: 67, 13: 68, 14: 69, 15: 70}
   s := ""
   for q := n; q > 0; q = q / 16 {
      m := q % 16
      if m > 9 && m < 16 {
         m = hex[m]
         s = fmt.Sprintf("%v%v", string(m), s)
         continue
      }
      s = fmt.Sprintf("%v%v", m, s)
   }
   return s
}

// Binary to decimal 二进制转十进制
func BinDec(b string) (n int64) {
   s := strings.Split(b, "")
   l := len(s)
   i := 0
   d := float64(0)
   for i = 0; i < l; i++ {
      f, err := strconv.ParseFloat(s[i], 10)
      if err != nil {
         log.Println("Binary to decimal error:", err.Error())
         return -1
      }
      d += f * math.Pow(2, float64(l-i-1))
   }
   return int64(d)
}

// Octal to decimal  八进制转十进制
func OctDec(o int64) (n int64) {
   s := strings.Split(strconv.Itoa(int(o)), "")
   l := len(s)
   i := 0
   d := float64(0)
   for i = 0; i < l; i++ {
      f, err := strconv.ParseFloat(s[i], 10)
      if err != nil {
         log.Println("Octal to decimal error:", err.Error())
         return -1
      }
      d += f * math.Pow(8, float64(l-i-1))
   }
   return int64(d)
}

// Hexadecimal to decimal 十六进制转十进制
func HexDec(h string) (n int64) {
   s := strings.Split(strings.ToUpper(h), "")
   l := len(s)
   i := 0
   d := float64(0)
   hex := map[string]string{"A": "10", "B": "11", "C": "12", "D": "13", "E": "14", "F": "15"}
   for i = 0; i < l; i++ {
      c := s[i]
      if v, ok := hex[c]; ok {
         c = v
      }
      f, err := strconv.ParseFloat(c, 10)
      if err != nil {
         log.Println("Hexadecimal to decimal error:", err.Error())
         return -1
      }
      d += f * math.Pow(16, float64(l-i-1))
   }
   return int64(d)
}

// Octal to binary 八进制转二进制
func OctBin(o int64) string {
   d := OctDec(o)
   if d == -1 {
      return ""
   }
   return DecBin(d)
}

// Hexadecimal to binary 十六进制转二进制
func HexBin(h string) string {
   d := HexDec(h)
   if d == -1 {
      return ""
   }
   return DecBin(d)
}

// Binary to octal 二进制转八进制
func BinOct(b string) int64 {
   d := BinDec(b)
   if d == -1 {
      return -1
   }
   return DecOct(d)
}

// Binary to hexadecimal 二进制转十六进制
func BinHex(b string) string {
   d := BinDec(b)
   if d == -1 {
      return ""
   }
   return DecHex(d)
}

一个硬核的16进制转10进制 看起来有点笨, 但是很有效

var b2m_map map[byte]uint64 = map[byte]uint64{
    0x00: 0,
    0x01: 1,
    0x02: 2,
    0x03: 3,
    0x04: 4,
    0x05: 5,
    0x06: 6,
    0x07: 7,
    0x08: 8,
    0x09: 9,
    0x0A: 10,
    0x0B: 11,
    0x0C: 12,
    0x0D: 13,
    0x0E: 14,
    0x0F: 15,
    0x10: 16,
    0x11: 17,
    0x12: 18,
    0x13: 19,
    0x14: 20,
    0x15: 21,
    0x16: 22,
    0x17: 23,
    0x18: 24,
    0x19: 25,
    0x1A: 26,
    0x1B: 27,
    0x1C: 28,
    0x1D: 29,
    0x1E: 30,
    0x1F: 31,
    0x20: 32,
    0x21: 33,
    0x22: 34,
    0x23: 35,
    0x24: 36,
    0x25: 37,
    0x26: 38,
    0x27: 39,
    0x28: 40,
    0x29: 41,
    0x2A: 42,
    0x2B: 43,
    0x2C: 44,
    0x2D: 45,
    0x2E: 46,
    0x2F: 47,
    0x30: 48,
    0x31: 49,
    0x32: 50,
    0x33: 51,
    0x34: 52,
    0x35: 53,
    0x36: 54,
    0x37: 55,
    0x38: 56,
    0x39: 57,
    0x3A: 58,
    0x3B: 59,
    0x3C: 60,
    0x3D: 61,
    0x3E: 62,
    0x3F: 63,
    0x40: 64,
    0x41: 65,
    0x42: 66,
    0x43: 67,
    0x44: 68,
    0x45: 69,
    0x46: 70,
    0x47: 71,
    0x48: 72,
    0x49: 73,
    0x4A: 74,
    0x4B: 75,
    0x4C: 76,
    0x4D: 77,
    0x4E: 78,
    0x4F: 79,
    0x50: 80,
    0x51: 81,
    0x52: 82,
    0x53: 83,
    0x54: 84,
    0x55: 85,
    0x56: 86,
    0x57: 87,
    0x58: 88,
    0x59: 89,
    0x5A: 90,
    0x5B: 91,
    0x5C: 92,
    0x5D: 93,
    0x5E: 94,
    0x5F: 95,
    0x60: 96,
    0x61: 97,
    0x62: 98,
    0x63: 99,
    0x64: 100,
    0x65: 101,
    0x66: 102,
    0x67: 103,
    0x68: 104,
    0x69: 105,
    0x6A: 106,
    0x6B: 107,
    0x6C: 108,
    0x6D: 109,
    0x6E: 110,
    0x6F: 111,
    0x70: 112,
    0x71: 113,
    0x72: 114,
    0x73: 115,
    0x74: 116,
    0x75: 117,
    0x76: 118,
    0x77: 119,
    0x78: 120,
    0x79: 121,
    0x7A: 122,
    0x7B: 123,
    0x7C: 124,
    0x7D: 125,
    0x7E: 126,
    0x7F: 127,
    0x80: 128,
    0x81: 129,
    0x82: 130,
    0x83: 131,
    0x84: 132,
    0x85: 133,
    0x86: 134,
    0x87: 135,
    0x88: 136,
    0x89: 137,
    0x8A: 138,
    0x8B: 139,
    0x8C: 140,
    0x8D: 141,
    0x8E: 142,
    0x8F: 143,
    0x90: 144,
    0x91: 145,
    0x92: 146,
    0x93: 147,
    0x94: 148,
    0x95: 149,
    0x96: 150,
    0x97: 151,
    0x98: 152,
    0x99: 153,
    0x9A: 154,
    0x9B: 155,
    0x9C: 156,
    0x9D: 157,
    0x9E: 158,
    0x9F: 159,
    0xA0: 160,
    0xA1: 161,
    0xA2: 162,
    0xA3: 163,
    0xA4: 164,
    0xA5: 165,
    0xA6: 166,
    0xA7: 167,
    0xA8: 168,
    0xA9: 169,
    0xAA: 170,
    0xAB: 171,
    0xAC: 172,
    0xAD: 173,
    0xAE: 174,
    0xAF: 175,
    0xB0: 176,
    0xB1: 177,
    0xB2: 178,
    0xB3: 179,
    0xB4: 180,
    0xB5: 181,
    0xB6: 182,
    0xB7: 183,
    0xB8: 184,
    0xB9: 185,
    0xBA: 186,
    0xBB: 187,
    0xBC: 188,
    0xBD: 189,
    0xBE: 190,
    0xBF: 191,
    0xC0: 192,
    0xC1: 193,
    0xC2: 194,
    0xC3: 195,
    0xC4: 196,
    0xC5: 197,
    0xC6: 198,
    0xC7: 199,
    0xC8: 200,
    0xC9: 201,
    0xCA: 202,
    0xCB: 203,
    0xCC: 204,
    0xCD: 205,
    0xCE: 206,
    0xCF: 207,
    0xD0: 208,
    0xD1: 209,
    0xD2: 210,
    0xD3: 211,
    0xD4: 212,
    0xD5: 213,
    0xD6: 214,
    0xD7: 215,
    0xD8: 216,
    0xD9: 217,
    0xDA: 218,
    0xDB: 219,
    0xDC: 220,
    0xDD: 221,
    0xDE: 222,
    0xDF: 223,
    0xE0: 224,
    0xE1: 225,
    0xE2: 226,
    0xE3: 227,
    0xE4: 228,
    0xE5: 229,
    0xE6: 230,
    0xE7: 231,
    0xE8: 232,
    0xE9: 233,
    0xEA: 234,
    0xEB: 235,
    0xEC: 236,
    0xED: 237,
    0xEE: 238,
    0xEF: 239,
    0xF0: 240,
    0xF1: 241,
    0xF2: 242,
    0xF3: 243,
    0xF4: 244,
    0xF5: 245,
    0xF6: 246,
    0xF7: 247,
    0xF8: 248,
    0xF9: 249,
    0xFA: 250,
    0xFB: 251,
    0xFC: 252,
    0xFD: 253,
    0xFE: 254,
    0xFF: 255,
}

func hex2int(hexB *[]byte) uint64 {
    var retInt uint64
    hexLen := len(*hexB)
    for k, v := range *hexB {
        retInt += b2m_map[v] * exponent(16, uint64(2*(hexLen-k-1)))
    }
    return retInt
}

6 - 日期时间函数

对2006-01-02 15:04:05 (go的诞生时间) 按照123456来记忆:01月02号 下午3点04分05秒 2006年

获得秒,毫秒,纳秒时间戳

fmt.Printf("时间戳(秒):%v;\n", time.Now().Unix())
fmt.Printf("时间戳(纳秒):%v;\n",time.Now().UnixNano())
fmt.Printf("时间戳(毫秒):%v;\n",time.Now().UnixNano() / 1e6)
fmt.Printf("时间戳(纳秒转换为秒):%v;\n",time.Now().UnixNano() / 1e9)

获取格式化的前 5秒,5分钟,5小时,5天,5个月,5年前的时间

对 分小时天月年 设置格式 Format(“2006-01-02 15:04:05”) —> Format(“2006-01-02 15:00:00”), 写成00就是把对应位置直接赋值成00

st,_ := time.ParseDuration("-5s")
fmt.Println("5秒前的时间:",time.Now().Add(st).Format("2006-01-02 15:04:05"))
fmt.Println("5秒前的时间:",time.Now().Add(time.Second*-5).Format("2006-01-02 15:04:05"))

st,_ = time.ParseDuration("-5m")
fmt.Println("5分前的时间:",time.Now().Add(st).Format("2006-01-02 15:04:05"))
fmt.Println("5分前的时间:",time.Now().Add(time.Minute*-5).Format("2006-01-02 15:04:05"))

st,_ = time.ParseDuration("-5h")
fmt.Println("5小时前的时间:",time.Now().Add(st).Format("2006-01-02 15:04:05"))
fmt.Println("5小时前的时间:",time.Now().Add(time.Hour*-5).Format("2006-01-02 15:04:05"))


fmt.Println("5天前的时间:",time.Now().AddDate(0, 0, -5).Format("2006-01-02 15:04:05"))

fmt.Println("5月前的时间:",time.Now().AddDate(0, -5, 0).Format("2006-01-02 15:04:05"))

fmt.Println("5年前的时间:",time.Now().AddDate(-5, 0, 0).Format("2006-01-02 15:04:05"))

外部传入字符串时间戳输出

package main

import (
    "log"
    "time"
)

func main() {

    t := int64(1595581744)   //外部传入的时间戳(秒为单位),必须为int64类型, time.Unix(t, 0)必须是到秒的时间戳
    t1 := "2019-01-08 13:50:30" //外部传入的时间字符串

    //时间转换的模板,golang里面只能是 "2006-01-02 15:04:05" (go的诞生时间)
    timeTemplate1 := "2006-01-02 15:04:05" //常规类型
    timeTemplate2 := "2006/01/02 15:04:05" //其他类型
    timeTemplate3 := "2006-01-02"          //其他类型
    timeTemplate4 := "15:04:05"            //其他类型

    // ======= 将时间戳格式化为日期字符串 =======
    log.Println(time.Unix(t, 0).Format(timeTemplate1)) //输出:2019-01-08 13:50:30
    log.Println(time.Unix(t, 0).Format(timeTemplate2)) //输出:2019/01/08 13:50:30
    log.Println(time.Unix(t, 0).Format(timeTemplate3)) //输出:2019-01-08
    log.Println(time.Unix(t, 0).Format(timeTemplate4)) //输出:13:50:30

    // ======= 将时间字符串转换为时间戳 =======
    stamp, _ := time.ParseInLocation(timeTemplate1, t1, time.Local) //使用parseInLocation将字符串格式化返回本地时区时间
    log.Println(stamp.Unix())                                       //输出:1546926630
}

7 - 数据类型转换

string to other = 字符串转其他

string -> int

i1, err := strconv.Atoi("1")

string -> int64

i64, err := strconv.ParseInt("2", 10, 64)

hexstring -> []byte 16进制字符串转(16进制代表的)byte数组

hex_str := "4161"
hex_data, _ := hex.DecodeString(hex_str)
fmt.Println(string(hexData))//Aa

8 - 数学函数

向上取整math.Ceil() 向下取整math.Floor()

//go没有其他语言得round函数,整数位得四舍五入简单版 func round(x float64){ return int(math.Floor(x + 0/5)) }

package main

import (
    "fmt"
    "github.com/shopspring/decimal"
)

/*
保有小数位得四舍五入
*/
func main() {
    v1, _ := decimal.NewFromFloat(9.824).Round(2).Float64()
    v2, _ := decimal.NewFromFloat(9.826).Round(2).Float64()
    v3, _ := decimal.NewFromFloat(9.8251).Round(2).Float64()
    fmt.Println(v1, v2, v3)

    v4, _ := decimal.NewFromFloat(9.815).Round(2).Float64()
    v5, _ := decimal.NewFromFloat(9.825).Round(2).Float64()
    v6, _ := decimal.NewFromFloat(9.835).Round(2).Float64()
    v7, _ := decimal.NewFromFloat(9.845).Round(2).Float64()
    fmt.Println(v4, v5, v6, v7)

    v8, _ := decimal.NewFromFloat(3.3).Round(2).Float64()
    v9, _ := decimal.NewFromFloat(3.3000000000000003).Round(2).Float64()
    v10, _ := decimal.NewFromFloat(3).Round(2).Float64()
    fmt.Println(v8, v9, v10)

    v11, _ := decimal.NewFromFloat(129.975).Round(2).Float64()
    v12, _ := decimal.NewFromFloat(34423.125).Round(2).Float64()
    fmt.Println(v11, v12)
}

9 - 文件目录操作函数

获取指定目录下正则匹配到的文件

package main

import (
    "fmt"
    "log"
    "os"
    "path/filepath"
)

func main() {

    files, err := WalkMatch("./", "*.exe")
    if err != nil {
        log.Fatalln(err)
    }
    fmt.Println(files)

}
func WalkMatch(root, pattern string) ([]string, error) {
    var matches []string
    err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        if info.IsDir() {
            return nil
        }
        if matched, err := filepath.Match(pattern, filepath.Base(path)); err != nil {
            return err
        } else if matched {
            path, _ = filepath.Abs(path)
            matches = append(matches, path)
        }
        return nil
    })
    if err != nil {
        return nil, err
    }
    return matches, nil
}

10 - 系统变量初始化

Context

ctx, _ := context.WithTimeout(context.Background(), 15 * time.Second)

获取当前路径

package main

import (
    "os"
    "path/filepath"
)

func main() {
    // 据说这个方法在某些特别场景会获取到错误的路径
    dir1, _ := os.Getwd()

    //推荐使用下面的方法
    dir2, _ := os.Executable()
    exPath := filepath.Dir(dir2)
    println(exPath2)
}

11 - 序列化

序列化存入内存

f,err = os.Open("path")
if err != nil {
    driver.logger.Error("文件打开失败:"+err.Error())
    os.Exit(-1)
}
dec := gob.NewDecoder(f)
err = dec.Decode(&helper.DeviceTerminalMap)
//判断有错误并且不是文件为空的错误,文件如果为空,在读文件是直接返回文件结束符(EOF)
if err != nil && err != io.EOF {
    driver.logger.Error("设备终端档案存储文件解析失败:"+err.Error())
    os.Exit(-1)
}

写入序列化内容

f, _ := os.Open("device-terminal.god")
defer f.Close()
dec := gob.NewDecoder(f)
err = dec.Decode(&helper.DeviceTerminalMap)

12 - 整型

int64 -> string

var i1 int64
i1 = 555
str1 := strconv.FormatInt(int1,10)

int -> string

i2 := 1
str2 := strconv.Itoa(i2)

int8 -> string

var int8Value int8
int8Value = 2
strconv.Itoa(int(int8Value))
//整形转换成字节
func IntToBytes(n int) []byte {
  x := int32(n)
  bytesBuffer := bytes.NewBuffer([]byte{})
  binary.Write(bytesBuffer, binary.BigEndian, x)
  return bytesBuffer.Bytes()
}
//字节转换成整形
func BytesToInt(b []byte) int {
  bytesBuffer := bytes.NewBuffer(b)
  
  var x int32
  binary.Read(bytesBuffer, binary.BigEndian, &x)
  
  return int(x)
}

13 - 字符串函数

生成UUID

package main

import (
    "github.com/satori/go.uuid"
    "fmt"
)

func main(){
    u1 := uuid.Must(uuid.NewV4())
    fmt.Printf("UUIDv4:%s\n", u1)

    u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
    if err != nil {
        fmt.Printf("Something went wrong: %s", err)
        return
    }
    fmt.Printf("Successfully parsed: %s", u2)
}

字符串拆分


//1. 按指定字符拆分
s := "iiaiibiiciiiidiiii"
sep:="ii"
arr:=strings.Split(s,sep)
fmt.Println("arr:",arr)

//2. 按空格拆分
s:=" ab cd          ef gh ij kl "
arr:=strings.Fields(s)
fmt.Printf("arr:%q\n",arr)

接收gbk编码的中文要转成utf8的中文

//github.com/axgle/mahonia
func ConvertToString(src string, srcCode string, tagCode string) string {
    srcCoder := mahonia.NewDecoder(srcCode)
    srcResult := srcCoder.ConvertString(src)
    tagCoder := mahonia.NewDecoder(tagCode)
    _, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
    result := string(cdata)
    return result
}
func main() {
    //gbk编码的中文,用16进制字符串表示
    hex_str := "4d6f646275732e58464a2e3330462ec0e4c4fdcbaec5c5cbaeb1c3"
    hex_data, _ := hex.DecodeString(hex_str)
    // 将 byte 转换 为字符串 输出结果
    str := ConvertToString(string(hex_data), "gbk", "utf-8")
    fmt.Println(str)

    //先试试这个,一般就可以了
    s1 := "4d6f646275732e58464a2e3330462ec0e4c4fdcbaec5c5cbaeb1c3"
    hex_data, _ := hex.DecodeString(s1)
    srcCoder := mahonia.NewDecoder("gbk")
    srcResult := srcCoder.ConvertString(string(hex_data))
    fmt.Println(srcResult)
}

MD5

package main

import (
"crypto/md5"
"fmt"
"io"
)

func main() {
str := "abc123"

//方法一
data := []byte(str)
has := md5.Sum(data)
md5str1 := fmt.Sprintf("%x", has) //将[]byte转成16进制

fmt.Println(md5str1)

//方法二

w := md5.New()
io.WriteString(w, str)   //将str写入到w中
md5str2: = fmt.Sprintf("%x", w.Sum(nil))  //w.Sum(nil)将w的hash转成[]byte格式

fmt.Println(mdtstr2)
}

Base64

package main

import (
   "encoding/base64"
   "fmt"
)

func main()  {

   //标准base64编码
   data:="abckagfd*^&&^*fadf";

   sEnc:=base64.StdEncoding.EncodeToString([]byte(data))

   fmt.Println(sEnc)

   sDec,_:=base64.StdEncoding.DecodeString(sEnc)

   fmt.Println(string(sDec))

   //兼容base64编码
   uEnc:=base64.URLEncoding.EncodeToString([]byte(data))

   fmt.Println(uEnc)

   uDec,_:=base64.URLEncoding.DecodeString(uEnc)
   fmt.Println(string(uDec))

}

字符串和[]byte相互转换

package main

import (
    "fmt"
    "reflect"
    "time"
    "unsafe"
)

//零拷贝字符串转字节数组
func string2bytes(s string) []byte {
    stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))
    var b []byte
    pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    pbytes.Data = stringHeader.Data
    pbytes.Len = stringHeader.Len
    pbytes.Cap = stringHeader.Len
    return b
}

//零拷贝字节数组转字符串
func bytes2string(b []byte) string {
    bHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    var s string
    stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))
    stringHeader.Data = bHeader.Data
    stringHeader.Len = bHeader.Len
    return s
}

func main() {
    s := "零拷贝转换字符串和字节数组"
    t1 := time.Now().Nanosecond()
    v := string2bytes(s)
    t2 := time.Now().Nanosecond()
    fmt.Println(v)

    t3 := time.Now().Nanosecond()
    data := []byte(s)
    t4 := time.Now().Nanosecond()
    fmt.Println(data)

    fmt.Println("method1 time", t2-t1)
    fmt.Println("method2 time", t4-t3)

    t5 := time.Now().Nanosecond()
    s1 := bytes2string(v)
    t6 := time.Now().Nanosecond()
    fmt.Println(s1)

    t7 := time.Now().Nanosecond()
    s2 := string(v)
    t8 := time.Now().Nanosecond()
    fmt.Println(s2)
    fmt.Println("method3 time", t6-t5)
    fmt.Println("method4 time", t8-t7)
}

14 - 字节数组操作([]byte)

//isSymbol表示有无符号
func BytesToInt(b []byte, isSymbol bool)  (int, error){
    if isSymbol {
        return bytesToIntS(b)
    }
    return bytesToIntU(b)
}
 
 
//字节数(大端)组转成int(无符号的)
func bytesToIntU(b []byte) (int, error) {
    if len(b) == 3 {
        b = append([]byte{0},b...)
    }
    bytesBuffer := bytes.NewBuffer(b)
    switch len(b) {
    case 1:
        var tmp uint8
        err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
        return int(tmp), err
    case 2:
        var tmp uint16
        err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
        return int(tmp), err
    case 4:
        var tmp uint32
        err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
        return int(tmp), err
    default:
        return 0,fmt.Errorf("%s", "BytesToInt bytes lenth is invaild!")
    }
}
 
 
 
//字节数(大端)组转成int(有符号)
func bytesToIntS(b []byte) (int, error) {
    if len(b) == 3 {
        b = append([]byte{0},b...)
    }
    bytesBuffer := bytes.NewBuffer(b)
    switch len(b) {
    case 1:
        var tmp int8
        err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
        return int(tmp), err
    case 2:
        var tmp int16
        err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
        return int(tmp), err
    case 4:
        var tmp int32
        err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
        return int(tmp), err
    default:
        return 0,fmt.Errorf("%s", "BytesToInt bytes lenth is invaild!")
    }
}
 
 
//整形转换成字节
func IntToBytes(n int,b byte) ([]byte,error) {
    switch b {
    case 1:
        tmp := int8(n)
        bytesBuffer := bytes.NewBuffer([]byte{})
        binary.Write(bytesBuffer, binary.BigEndian, &tmp)
        return bytesBuffer.Bytes(),nil
    case 2:
        tmp := int16(n)
        bytesBuffer := bytes.NewBuffer([]byte{})
        binary.Write(bytesBuffer, binary.BigEndian, &tmp)
        return bytesBuffer.Bytes(),nil
    case 3,4:
        tmp := int32(n)
        bytesBuffer := bytes.NewBuffer([]byte{})
        binary.Write(bytesBuffer, binary.BigEndian, &tmp)
        return bytesBuffer.Bytes(),nil
    }
    return nil,fmt.Errorf("IntToBytes b param is invaild")
}