我已经找到了encoding/binary个包来处理它,但它依赖于reflect个包,所以它不能处理未资本化(即未报告的) struct 字段.然而,我花了一周的时间来解决这个问题,我仍然有一个问题:如果不应该导出struct字段,我如何轻松地将它们转储到二进制数据中?

这里有个例子.如果将Data struct的字段名称大写,则可以正常工作.但是Datastruct是一个抽象类型,所以我不想导出这些字段.

package main
import (
    "fmt"
    "encoding/binary"
    "bytes"
)

type Data struct {
    id int32
    name [16]byte
}


func main() {
    d := Data{Id: 1}
    copy(d.Name[:], []byte("tree"))
    buffer := new(bytes.Buffer)
    binary.Write(buffer, binary.LittleEndian, d)
    // d was written properly
    fmt.Println(buffer.Bytes())
    // try to read...
    buffer = bytes.NewBuffer(buffer.Bytes())
    var e = new(Data)
    err := binary.Read(buffer, binary.LittleEndian, e)
    fmt.Println(e, err)
}

推荐答案

最好的 Select 可能是使用gob package,让 struct 实现GobDecoderGobEncoder接口,以便序列化和反序列化私有字段.

这将是安全的、平台无关的和高效的.而且您必须仅在具有未导出字段的 struct 上添加那些GobEncode和GobDecode函数,这意味着您不会将代码的睡觉弄得乱七八糟.

func (d *Data) GobEncode() ([]byte, error) {
    w := new(bytes.Buffer)
    encoder := gob.NewEncoder(w)
    err := encoder.Encode(d.id)
    if err!=nil {
        return nil, err
    }
    err = encoder.Encode(d.name)
    if err!=nil {
        return nil, err
    }
    return w.Bytes(), nil
}

func (d *Data) GobDecode(buf []byte) error {
    r := bytes.NewBuffer(buf)
    decoder := gob.NewDecoder(r)
    err := decoder.Decode(&d.id)
    if err!=nil {
        return err
    }
    return decoder.Decode(&d.name)
}

func main() {
    d := Data{id: 7}
    copy(d.name[:], []byte("tree"))
    buffer := new(bytes.Buffer)
    // writing
    enc := gob.NewEncoder(buffer)
    err := enc.Encode(d)
    if err != nil {
        log.Fatal("encode error:", err)
    }
    // reading
    buffer = bytes.NewBuffer(buffer.Bytes())
    e := new(Data)
    dec := gob.NewDecoder(buffer)
    err = dec.Decode(e)
    fmt.Println(e, err)
}

Go相关问答推荐

在保留额外参数的同时解封YAML

../golang/pkg/mod/github.com/wmentor/lemmas@v0.0.6/processor.go:72:9:未定义:令牌.进程

在GO中使用泛型类型 struct 实现接口方法

如果values.yaml文件中不存在某个属性,如何返回默认的FALSE?

无法获取RPC描述符

JWT 如何解析声明有效性和错误?

如何使用gosdk在Dynamodb中进行UpdateItem时,将ValueBuilder对象声明为StringSet类型?

在 Go 中解组编号的 XML 标签

gopacket:IP-in-IP 数据包上的解码层

将文本文件放入切片然后进行比较

当图像是对象数组的元素时,如何显示存储为页面资源的图像?

go - 仅在函数即将返回错误时清理资源

无法使用 Golang 扫描文件路径

如何根据 Go 中第二次出现的分隔符拆分字符串?

Golang Getrlimit 返回与 ulimit 不同的值

Gorm 在保存/创建时序列化 struct

Golang 数据库/sql 与 SetMaxOpenConns 挂起

在 golang 中联合一个接口和类型

手动将 OpenTelemetry 上下文从 golang 提取到字符串中?

Go Flag 用法 描述 包含 Word 值