编程笔记

lifelong learning & practice makes perfect

golang technique

go-repo code snippet

  1. 判断机器位数

    1
    const intSize = 32 << (^uint(0) >> 63)

    在64平台系统:
      1. uint(0)在平台底层是0x0000000000000000
      2. ^uint(0)在平台底层是0xFFFFFFFFFFFFFFFF
      3. ^uint(0) >> 63 在底层平台是0x0000000000000001,也就是1
      4. 32 << 1 结果是32*2 = 64

data conversion

  1. 充分利用已有的实现
1
2
3
4
5
6
7
8
9
10
11
12
type Sorter interface{
Sort()[]int
}

// 自己实现需要为Sequence实现container包内的接口,转换可以利用已有的代码

type Sequence []int
func (s Sequence)Sort()[]int{
copy:=make(Sequence,0,len(s))
append(copy,s...)
sort.IntSlice(s).Sort()
}
  1. 断言防止panic,使用安全方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var list interface{}
    list=&Sequence{1,2,4,3}
    // 不安全方式,assertion不成功,会panic
    convert:=list.(*Sequence)

    // 安全方式
    convert,ok:=list.(*Sequence)
    if !ok{
    return errors.New("convert error")
    }
  2. 反射,通过CanSet()判断反射得到的值能否修改

    1
    2
    3
    var f float64=3
    val:=reflect.ValueOf(x)
    val.CanSet()

    反射在标准库中大量使用,fmt.Fprintf及其他格式化函数大多使用反射实现;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //fmt.Fprintf
    func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
    p := newPrinter()
    p.doPrintf(format, a)
    n, err = w.Write(p.buf)
    p.free()
    return
    }

    // 判断interface的类型,在go 1.15 ".(type)"只能在switch使用
    var i interface{}=&os.File{}
    switch val.(type){
    case int:
    case *os.File:
    case string:
    }

参考文档

  1. golang官方文档 https://golang.google.cn/doc/effective_go#pointers_vs_values
  2. uber代码规范 (https://github.com/uber-go/guide)
  3. code snippet https://www.cnblogs.com/keystone/p/13930136.html

欢迎关注我的其它发布渠道