如何在不反射的情况下将结构转储到字节数组中?
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?
EDIT: 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)
}
我已经找到编码/二进制软件包来处理它,但是它依赖于 reflect 包,因此它不适用于未大写(即未导出)的结构字段。 但是我花了一周的时间才发现这个问题,但是我仍然有一个问题:如果不应该导出结构字段,如何将它们轻松转储到二进制数据中? p>
EDIT : strong>这是示例。 如果大写 Data code>结构的字段名称,则可以正常工作。 但是
Data code>结构原本是一种抽象类型,所以我不想导出这些字段。 p>
包main
import(
“ fmt”
“ encoding / binary”
“ bytes”
)
type数据结构{
id int32
名称[16] byte
} \ n
func main(){
d:=数据{Id:1}
复制(d.Name [:],[] byte(“ tree”))
buffer:= new(bytes.Buffer)
binary.Write(buffer,binary.LittleEndian,d)
//正确写入d
fmt.Println(buffer.Bytes())
//尝试读取...
buffer =字节。 NewBuffer(buffer.Bytes())
var e = new(Data)
err:= binary.Read(buffer,binary.LittleEndian,e)
fmt.Println(e,err)
}
pre>
div>
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.
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)
}