29 July 2014
看布隆过滤器源码https://github.com/willf/bloom,里面用了binary包,在这里做记录。

在C语言笔试的时候,比较喜欢考这个东西,如何将一个char数组转成int类型。当年看过,不过早就忘记了。后来看到这种东西binary.BigEndian.Uint32(a),直接瞎了。后来去看文档,看了半天也没搞明白。

在这里直接说一下,源码。下面这个是uint8,也就是byte数组,大小为4,转换成int32的代码。

package main

import "fmt"
import "encoding/binary"

func main() {
	var a []byte = []byte{0, 1, 2, 3}
	fmt.Println(a)
	fmt.Println(binary.BigEndian.Uint32(a))
	fmt.Println(binary.LittleEndian.Uint32(a))
}

执行结果:

[0 1 2 3]
66051
50462976

转换有两种不同的方式,也就是大端和小端。大端就是内存中低地址对应着整数的高位。按照上面的例子说,就是按照0123的顺序拼成int32,整数的最高8位是0,接着是1,以此类推,所以是66051。小端就是反过来,最高8位是3,也就是00000101,这样最后得到50462976。

在Golang源码目录encoding/binary.go下,有函数的实现。不过里面没有对byte数组长度的检查,如果传入的数组长度小于4,自然会报错:panic: runtime error: index out of range

func (bigEndian) Uint32(b []byte) uint32 {
	return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
}

上面讲的BigEndianLittleEndian都是实现类,都是实现的类ByteOrder

type ByteOrder interface {
    Uint16([]byte) uint16
    Uint32([]byte) uint32
    Uint64([]byte) uint64
    PutUint16([]byte, uint16)
    PutUint32([]byte, uint32)
    PutUint64([]byte, uint64)
    String() string
}

参考文献

原文链接:Golang binary包——byte数组如何转int?,转载请注明来源!

EOF