前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2022-06-13:golang中,[]byte和结构体如何相互转换?

2022-06-13:golang中,[]byte和结构体如何相互转换?

作者头像
福大大架构师每日一题
发布2023-06-08 14:25:01
4890
发布2023-06-08 14:25:01
举报
文章被收录于专栏:福大大架构师每日一题

2022-06-13:golang中,[]byte和结构体如何相互转换?

答案2022-06-13:

[]byte和结构体的转换的应用场景是数据解析。

代码里有两种方法,一种是内存不共用,另一种是内存共用。

[]byte转结构体严格将首地址需要是8的倍数。但代码里并没有遵守这个规则,测试后也没问题。

但有些场合需要严格遵守这个规则,否则会出现问题。

虽然这里没出现问题,但是结构体首地址最好是8的整数倍。不过很多CPU帮你解决了。MIPS会直接崩溃。

这里没出现问题,那是因为很多CPU帮你解决了。MIPS会直接崩溃。这个答案来自qq群友。我并没有去验证。

代码用golang编写。代码如下:

代码语言:javascript
复制
package main

import (
  "bytes"
  "encoding/binary"
  "fmt"
  "unsafe"
)

type T struct {
  A int64
  B float64
}

func main() {
  if true {
    fmt.Println("切片和结构体内存不共用")
    // Create a struct and write it.
    t := T{A: 1, B: 3.14}
    buf := &bytes.Buffer{}
    err := binary.Write(buf, binary.LittleEndian, t)
    if err != nil {
      panic(err)
    }
    fmt.Println(buf.Bytes())

    // Read into an empty struct.
    t = T{}
    err = binary.Read(buf, binary.LittleEndian, &t)
    if err != nil {
      panic(err)
    }
    fmt.Printf("%x %f\r\n", t.A, t.B)
  }
  fmt.Println("-------------------------")
  if true {
    fmt.Println("切片和结构体内存共用")
    t1 := T{A: 1, B: 3.14}
    fmt.Println("原结构体:", t1)
    sm1 := SimulatedSlice{
      Addr: unsafe.Pointer(&t1),
      Len:  int(unsafe.Sizeof(t1)),
      Cap:  int(unsafe.Sizeof(t1)),
    }
    bytes1 := *(*[]byte)(unsafe.Pointer(&sm1))
    bytes1[0] = 2
    fmt.Println("修改切片,结构体变成:", t1)
    fmt.Println(bytes1)
    fmt.Println("")

    bytes2 := []byte{1, 3, 0, 0, 0, 0, 0, 0, 0, 31, 133, 235, 81, 184, 30, 9, 64}
    fmt.Println("原切片:", bytes2)
    t2 := (*T)(unsafe.Pointer(&bytes2[1]))
    t2.A = 4
    fmt.Println("以为会有内存对齐问题,实际上没问题。修改结构体,切片变成:", bytes2)
    fmt.Println(t2)
    fmt.Println("地址不是8的整数倍:", uintptr(unsafe.Pointer(&bytes2[1])))
    fmt.Println("地址不是8的整数倍:", uintptr(unsafe.Pointer(t2)))
    fmt.Println("严格将首地址需要是8的倍数。")
    fmt.Println("一般也没事。")
    fmt.Println("但有些场合需要严格遵守这个规则,否则会出现问题。")
    fmt.Println("虽然这里没出现问题,但是结构体首地址最好是8的整数倍。不过很多CPU帮你解决了。MIPS会直接崩溃。")
    fmt.Println("这里没出现问题,那是因为很多CPU帮你解决了。MIPS会直接崩溃。这个答案来自qq群友。我并没有去验证。")

  }
}

type SimulatedSlice struct {
  Addr unsafe.Pointer
  Len  int
  Cap  int
}

执行结果如下:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档