1

我正在为我的项目使用 GOB 编码,我发现(经过长时间的斗争)空字符串没有正确编码/解码。在我的代码中,我使用错误消息(字符串)来报告任何问题,这个错误消息大部分时间都是空的。如果我编码一个空字符串,它就什么都没有了,这给我解码带来了问题。我不想更改编码/解码,因为这些部分使用得最多。我如何告诉 Go 如何编码/解码空字符串?

示例: 游乐场工作代码。 操场不工作的代码。

4

1 回答 1

1

问题不在于encoding/gob模块,而在于您为 声明的自定义MarshalBinary/方法,它无法正确往返空字符串。有两种方法可以去这里:UnmarshalBinaryMsg

  1. 摆脱MarshalBinary/UnmarshalBinary方法并依赖 GOB 对结构的默认编码。仅此更改还不够,因为未导出结构的字段。如果您愿意导出这些字段,那么这是最简单的选项: https: //play.golang.org/p/rwzxTtaIh2

  2. 使用可以正确往返空字符串的编码。一种简单的选择是使用 GOB 本身对结构字段进行编码:

    func (m Msg) MarshalBinary() ([]byte, error) {
        var b bytes.Buffer
        enc := gob.NewEncoder(&b)
        if err := enc.Encode(m.x); err != nil {
            return nil, err
        }
        if err := enc.Encode(m.y); err != nil {
            return nil, err
        }
        if err := enc.Encode(m.z); err != nil {
            return nil, err
        }
        return b.Bytes(), nil
    }
    
    // UnmarshalBinary modifies the receiver so it must take a pointer receiver.
    func (m *Msg) UnmarshalBinary(data []byte) error {
        dec := gob.NewDecoder(bytes.NewBuffer(data))
        if err := dec.Decode(&m.x); err != nil {
            return err
        }
        if err := dec.Decode(&m.y); err != nil {
            return err
        }
        return dec.Decode(&m.z)
    }
    

    你可以在这里试验这个例子:https: //play.golang.org/p/oNXgt88FtK

第一个选项显然更容易,但是如果您的实际示例稍微复杂一点,则第二个选项可能会很有用。但请注意自定义编码器:GOB 包含一些旨在检测不兼容性的功能(例如,如果您将字段添加到结构并尝试解码旧数据),这些自定义编码中缺少这些功能。

于 2014-12-04T07:25:03.117 回答