在网络传输过程中,经常会这样处理: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的指针了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

标签:
golang,struct,[]byte相互转换,golang,struct,[]byte

免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
评论“golang中struct和[]byte的相互转换示例”
暂无“golang中struct和[]byte的相互转换示例”评论...

RTX 5090要首发 性能要翻倍!三星展示GDDR7显存

三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。

首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。

据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。