2022-06-13:golang中,[]byte和结构体如何相互转换?
Posted 福大大架构师每日一题
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022-06-13:golang中,[]byte和结构体如何相互转换?相关的知识,希望对你有一定的参考价值。
2022-06-13:golang中,[]byte和结构体如何相互转换?
答案2022-06-13:
[]byte和结构体的转换的应用场景是数据解析。
代码里有两种方法,一种是内存不共用,另一种是内存共用。
[]byte转结构体严格将首地址需要是8的倍数。但代码里并没有遵守这个规则,测试后也没问题。
但有些场合需要严格遵守这个规则,否则会出现问题。
虽然这里没出现问题,但是结构体首地址最好是8的整数倍。不过很多CPU帮你解决了。MIPS会直接崩溃。
这里没出现问题,那是因为很多CPU帮你解决了。MIPS会直接崩溃。这个答案来自qq群友。我并没有去验证。
代码用golang编写。代码如下:
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 := TA: 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 := TA: 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 := []byte1, 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:golang中,[]byte和结构体如何相互转换?的主要内容,如果未能解决你的问题,请参考以下文章