golang struct 和 []byte 互转

example1

type MyStruct struct {
    A int
    B int
}

var sizeOfMyStruct = int(unsafe.Sizeof(MyStruct{}))

func MyStructToBytes(s *MyStruct) []byte {
    var x reflect.SliceHeader
    x.Len = sizeOfMyStruct
    x.Cap = sizeOfMyStruct
    x.Data = uintptr(unsafe.Pointer(s))
    return *(*[]byte)(unsafe.Pointer(&x))
}

func BytesToMyStruct(b []byte) *MyStruct {
    return (*MyStruct)(unsafe.Pointer(
        (*reflect.SliceHeader)(unsafe.Pointer(&b)).Data,
    ))
}

example2

import (
    "fmt"
    "unsafe"
)
type TestStructTobytes struct {
    data int64
}
type SliceMock struct {
    addr uintptr
    len  int
    cap  int
}

func main() {

    var testStruct = &TestStructTobytes{100}
    Len := unsafe.Sizeof(*testStruct)
    testBytes := &SliceMock{
        addr: uintptr(unsafe.Pointer(testStruct)),
        cap:  int(Len),
        len:  int(Len),
    }
    data := *(*[]byte)(unsafe.Pointer(testBytes))
    fmt.Println("[]byte is : ", data)
    var ptestStruct *TestStructTobytes = *(**TestStructTobytes)(unsafe.Pointer(&data))
    fmt.Println("ptestStruct.data is : ", ptestStruct.data)
}

// 由于在golang中编译器不将[]byte视为指针,所以要使用其地址进行转换,由于[]byte底层存放的是指向数据的地址。用[]byte的地址就需要使用双层指针转换,然后再指向其内容,得出来的就是转换对应struct的指针了。

高效的字符串和字节数组转换

func bytes2str(b []byte) string {
	return *(*string)(unsafe.Pointer(&b))
}

func str2bytes(s string) []byte {
	x := (*[2]uintptr)(unsafe.Pointer(&s)) // 获取s的起始地址开始后的两个 uintptr 指针
	h := [3]uintptr{x[0], x[1], x[1]}      // 构造三个指针数组
	return *(*[]byte)(unsafe.Pointer(&h))
}
posted @ 2020-06-04 09:58  白云辉  阅读(8238)  评论(0编辑  收藏  举报