Struct 如何在没有反射的情况下将结构转储到字节数组中?

Struct 如何在没有反射的情况下将结构转储到字节数组中?,struct,binary,bytearray,go,structure,Struct,Binary,Bytearray,Go,Structure,我已经找到了处理它的包,但它依赖于包,所以它不能处理未资本化(即未报告的)结构字段。然而,我花了一周的时间来找出这个问题,我仍然有一个问题:如果不应该导出结构字段,我如何将它们轻松地转储到二进制数据中 编辑:以下是示例。如果将Datastruct的字段名称大写,则该操作正常。但是Datastruct是一个抽象类型,所以我不想导出这些字段 主程序包 进口( “fmt” “编码/二进制” “字节” ) 类型数据结构{ id int32 名称[16]字节 } func main(){ d:=数据{Id

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

编辑:以下是示例。如果将
Data
struct的字段名称大写,则该操作正常。但是
Data
struct是一个抽象类型,所以我不想导出这些字段

主程序包
进口(
“fmt”
“编码/二进制”
“字节”
)
类型数据结构{
id int32
名称[16]字节
}
func main(){
d:=数据{Id:1}
副本(d.Name[:],[]字节(“树”))
缓冲区:=新的(字节.缓冲区)
binary.Write(缓冲区,binary.LittleEndian,d)
//d写得很好
fmt.Println(buffer.Bytes())
//试着读。。。
buffer=bytes.NewBuffer(buffer.bytes())
var e=新(数据)
err:=binary.Read(缓冲区,binary.LittleEndian,e)
fmt.Println(e,err)
}

最好的选择可能是使用,并让结构实现和接口,以便序列化和反序列化私有字段

这将是安全、独立于平台且高效的。您必须只在具有未报告字段的结构上添加那些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)
}

只是为了确保理解:您想要序列化结构以便能够在之后反序列化它们?你的反序列化程序会知道反序列化到什么结构中吗?嗨!您有任何示例代码吗?您期望的输出示例?如果您只是尝试原始二进制转储,
unsafe
可以执行您想要的操作。这取决于需要。@kroisse:正如所说,这取决于需要:)。是的,考虑到平台独立性,skip
unsafe
实现这一点的传统方法(主要是语言不可知的)是创建一个单独的结构,用于将程序中用于逻辑的结构与用于网络连接的结构分开。i、 e.创建单独的WireData结构,在序列化WireData之前将结构数据转换为WireData,并在接收数据时转换为oposite。WireData只保留需要序列化的数据中的信息。这是一个很好的解决方案!我试着用这种方式为每个字段手动使用binary.Read/Write,但是这段代码更接近标准。但是我应该匹配序列化结构的布局和大小。Gob stream附加了一些元数据来自我描述数据本身,因此布局被破坏。@dystroy,如果对象包含另一个对象等,我们如何处理您的解决方案?@Minty它是自动递归的,因此没有问题。当您有要序列化的未报告字段或要自定义序列化时,只需添加这两个函数。谢谢,我需要尝试一下。@我正在尝试为具有通道和函数类型的结构类型编写自定义GobEncode/decode。您的解决方案帮助我移动,但仍停留在上述类型上。请您扩展您的建议。谢谢!!