golang中struct和[]byte的相互转换

本文介绍了在Golang中如何高效地进行struct和[]byte之间的转换,利用unsafe包及类型转换实现。转换时需要注意struct中不能包含指针类型。详细展示了struct转[]byte以及[]byte转struct的过程,并解释了转换背后的原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在网络传输过程中,经常会这样处理:socket接收到数据,先获取其消息头,然后再做各种不同的业务处理。在解析消息头的时候的方法有多种多样。其中最为高效解析消息头的方法就是直接把数据头部分强制类型转换为对应的消息头结构体。这种做法在C/C++中非常的常见。而golang其实也是可以这样子做的。类似这样的应用,直接类型转换获取消息对应的解析方法其实效率会相对较高。
golang中struct和[]byte的转换方法,其实就是用到了golang中的unsafe包加上类型转换 , 约束:struct中不能有指针类型。
1、struct转化为[]byte,转换方法如下:

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)
}

运行结果:

[]byte is :  [100 0 0 0 0 0 0 0]

因为[]byte底层的数据结构为:
struct {
addr uintptr
len int
cap int
}
其中addr为数值的地址,len为当地数值的长度,cap为数值的容量。
转换的时候,需要定义一个和[]byte底层结构一致的struct(如例子中的SliceMock),然后把结构体的地址赋给addr,结构体的大小赋给len和cap。最后将其转换为[]byte类型。

2、将[]byte转换为struct,转换方法如下:

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)
}

运行结果:

[]byte is :  [100 0 0 0 0 0 0 0]
ptestStruct.data is :  100

从上面的例子中将[]byte转换为struct的代码片段为:

var ptestStruct *TestStructTobytes = *(**TestStructTobytes)(unsafe.Pointer(&data))

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

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值