我已经找到了编码/二进制包来处理它,但是它依赖于反射包,因此它不适用于未大写(即未导出)的结构域。但是我花了一周的时间才发现这个问题,但我仍然有一个问题:如果不应该导出结构字段,如何将它们轻松转储为二进制数据?
编辑: 这是示例。如果将大写的Datastruct 字段大写,则可以正常工作。但是Datastruct原本是一种抽象类型,所以我不想导出这些字段。
Data
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包,并让您的结构实现GobDecoder和GobEncoder接口,以便对私有字段进行序列化和反序列化。
这将是安全,独立于平台且高效的。而且,您必须仅在具有未导出字段的结构上添加这些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) }