为什么将两个不同的对象解码为同一个对象,但是bool成员没有更改?

时间:2019-05-21 01:59:31

标签: go gob

我正在使用go的编码/对象将类型为T的两个不同对象解码为同一对象,但是在第二次解码后,该对象的bool成员没有更改。为什么?

package main

import (
    "fmt"
    "encoding/gob"
    "bytes"
)

type T struct {
    X int
    Y string
    Z bool
}

func main() {
    t := T{}
    buf := new(bytes.Buffer)
    enc := gob.NewEncoder(buf)
    dec := gob.NewDecoder(buf)

    t1 := T{1, "1", true}
    enc.Encode(t1)
    dec.Decode(&t)
    fmt.Printf("%+v\n", t)

    // If t is a new entity, the second decode into t can product expected result: {X:2 Y:2 Z:false}
    // otherwise, t's bool member has not been changed after the second decode.
    // t = T{}
    t2 := T{2, "2", false}
    enc.Encode(t2)
    dec.Decode(&t)
    fmt.Printf("%+v\n", t)

    // result:
    // {X:1 Y:1 Z:true}
    // {X:2 Y:2 Z:true}
}

2 个答案:

答案 0 :(得分:2)

基于文档:https://golang.org/pkg/encoding/gob/#hdr-Encoding_Details

  

如果字段的类型值为零(数组除外,请参见上文),则将其从传输中省略。

“ false”为零值。如果您尝试设置C:\WorkSpace>stack HelloWorld.hs Downloading lts-13.7 build plan ... RedownloadHttpError (HttpExceptionRequest Request { host = "raw.githubusercontent.com" port = 443 secure = True requestHeaders = [("User-Agent","The Haskell Stack")] path = "/fpco/lts-haskell/master//lts-13.7.yaml" queryString = "" method = "GET" proxy = Nothing rawBody = False redirectCount = 10 responseTimeout = ResponseTimeoutDefault requestVersion = HTTP/1.1 } ConnectionTimeout) Access violation in generated code when reading 00007ffc39deffff ,它将显示相同的行为。

答案 1 :(得分:0)

意外的行为来自重复使用内存而不清理内存。 您重复使用了两次t和b,这使您面临许多可能的错误。这不是引起您的问题的原因,但也可能是b。

正如nvcnvn回答的那样,gob编码不考虑类型中具有0值的字段是一种预期的行为。请参阅编码结构的字节数,其大小增加:https://play.golang.org/p/HCz8-2kXHQX

如果您想重用bytes.Buffer而没有任何额外的分配并且很安全,请重置其值:https://golang.org/pkg/bytes/#Buffer.Reset