这两种数据结构在数据解析中很常见,需要做转换,如果有看过 你了解unsafe.Pointer这个不安全指针吗? 这篇文章,那就更好办了,在go语言中,我们知道指针类型直接转换是不行的,需要借助这个不安全指针来做桥梁。
struct转换成[]byte
想要转换成[]byte,字节数组我们看源码其实知道,是无符号8位整型:type byte = uint8,它的真实构造其实跟slice一样
type slice struct {
array unsafe.Pointer // 指向底层数组
len int // 长度,必选
cap int // 容量,可选
}
那么我们就模拟这样一个类似的数据结构:
package main
import (
"fmt"
"unsafe"
)
type Info struct {
data int64
data2 float64
}
type SimulatedSlice struct {
array uintptr
len int
cap int
}
func main() {
var info = &Info{80, 1.23}
Len := unsafe.Sizeof(*info)
simSlice := &SimulatedSlice{
array: uintptr(unsafe.Pointer(info)),
cap: int(Len),
len: int(Len),
}
data := *(*[]byte)(unsafe.Pointer(simSlice))
fmt.Printf("%#v,%v\n", data, data)
}
//[]byte{0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xae, 0x47, 0xe1, 0x7a, 0x14, 0xae, 0xf3, 0x3f},[80 0 0 0 0 0 0 0 174 71 225 122 20 174 243 63]
可以看到结构体的两个成员变量都分别转成了8位无符号的整型数组了。
[]byte转换成struct
上面是结构体转成了字节数组对吧,然后我们将生成的字节数组转换成结构体,也可以验证是否正确:
var mystruct *Info = *(**Info)(unsafe.Pointer(&data))
fmt.Printf("%#v,%#v,%#v", mystruct, mystruct.data, mystruct.data2)
//&main.Info{data:80, data2:1.23},80,1.23
可以看出结果没有问题,将data生成的字节数组还原成了结构体。