我如何转储到结构不反射的字节数组? [英] How do I dump the struct into the byte array without reflection?
问题描述
我已经找到编码/二进制包对付它,但它依靠的反映包,以便它不与小写形式工作(即,取消导出)结构域。不过,我花了一个星期来发现问题出来了,我还有一个问题:如果结构字段不应该出口,我怎么甩掉他们很容易地转换成二进制数据。
? 编辑:这里的例子。如果利用数据
结构的字段的名称,即正常工作。但数据
结构意欲是一个抽象类,所以我不希望导出这些字段。
主包
进口(
FMT
编码/二进制
字节
)类型数据结构{
ID INT32
名字[16]字节
}
FUNC的main(){
D:= {数据编号:1}
副本(d.Name [:],[]字节(树))
缓冲区:=新(bytes.Buffer)
binary.Write(缓冲,binary.LittleEndian,D)
//天得到了正确写入
fmt.Println(buffer.Bytes())
//尝试读取...
缓冲= bytes.NewBuffer(buffer.Bytes())
变种E =新的(数据)
错误:= binary.Read(缓冲,binary.LittleEndian,E)
fmt.Println(即错误)
}
您最好的选择很可能是使用采空包一>,让你的结构实现 GobDe codeR 并的GobEn$c$cr 为了接口,序列化和反序列化的私人领域。
这将是安全的,独立于平台,高效。而且你要添加这些GobEn code和GobDe code函数只与未导出字段结构,这意味着你不会堆积在code的其余部分。
FUNC(D *数据)GobEn code()([]字节,错误){
W:=新(bytes.Buffer)
EN codeR:= gob.NewEn codeR(W)
错误:= EN coder.En code(d.id)
如果犯错!= {为零
返回nil,ERR
}
ERR = EN coder.En code(d.name)
如果犯错!= {为零
返回nil,ERR
}
返回w.Bytes(),零
}FUNC(D *数据)GobDe code(BUF []字节)的错误{
R:= bytes.NewBuffer(BUF)
德codeR:= gob.NewDe codeR(R)
错误:=去coder.De code(安培; d.id)
如果犯错!= {为零
返回ERR
}
返回德coder.De code(安培; d.name)
}FUNC的main(){
D:= {数据ID:7}
副本(d.name [:],[]字节(树))
缓冲区:=新(bytes.Buffer)
// 写作
ENC:= gob.NewEn codeR(缓冲)
错误:= enc.En code(D)
如果犯错!= {为零
log.Fatal(EN code错误:ERR)
}
// 读
缓冲= bytes.NewBuffer(buffer.Bytes())
E:=新的(数据)
12月:= gob.NewDe codeR(缓冲)
ERR = dec.De code(E)
fmt.Println(即错误)
}
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)
}
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)
}
这篇关于我如何转储到结构不反射的字节数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!