如何在没有反射的情况下将结构转储到字节数组中? [英] How do I dump the struct into the byte array without reflection?

查看:50
本文介绍了如何在没有反射的情况下将结构转储到字节数组中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经找到了 encoding/binary 包来处理它,但这取决于reflect 包,因此它不适用于未大写(即未导出)的结构字段.不过我花了一个星期才找到这个问题,我仍然有一个问题:如果不应该导出结构字段,我如何轻松地将它们转储到二进制数据中?

I already found encoding/binary package to deal with it, but it depended on reflect package so it didn't work with uncapitalized(that is, unexported) struct fields. However I spent a week to find that problem out, I still have a question: if struct fields should not be exported, how do I dump them easily into binary data?

这是示例.如果您将 Data 结构的字段名称大写,则可以正常工作.但是 Data 结构体是一个抽象类型,所以我不想导出这些字段.

Here's the example. If you capitalize the name of fields of Data struct, that works properly. But Data struct was intended to be an abstract type, so I don't want to export these fields.

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

推荐答案

您最好的选择可能是使用 gob 包 并让您的结构实现 GobDecoderGobEncoder 接口,用于序列化和反序列化私有字段.

Your best option would probably be to use the gob package and let your struct implement the GobDecoder and GobEncoder interfaces in order to serialize and deserialize private fields.

这将是安全、独立于平台且高效的.而且您必须仅在具有未导出字段的结构体上添加这些 GobEncode 和 GobDecode 函数,这意味着您不会混淆其余的代码.

This would be safe, platform independent, and efficient. And you have to add those GobEncode and GobDecode functions only on structs with unexported fields, which means you don't clutter the rest of your code.

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

这篇关于如何在没有反射的情况下将结构转储到字节数组中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆