【问题标题】:How to encode/decode a empty string如何编码/解码一个空字符串
【发布时间】:2014-12-04 15:25:03
【问题描述】:

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

示例: Playground 工作代码。 Playground 代码无效。

【问题讨论】:

  • 查看示例,问题在于您的自定义 MarshalBinary/UnmarshalBinary 方法而不是 gob。如果您导出结构中的字段(将它们设为大写)并仅使用默认的 gob 编组,则您的示例有效。
  • @James Henstridge 谢谢,它完美无瑕。发布答案,以便我可以将您标记为答案。顺便说一句,有人必须更新文档,因为我不知道大写字段会解决我第一次遇到的另一个问题。

标签: encoding character-encoding go gob


【解决方案1】:

问题不在于encoding/gob 模块,而是您为Msg 声明的自定义MarshalBinary/UnmarshalBinary 方法,它无法正确往返空字符串。您可以通过两种方式访问​​这里:

  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 包含一些旨在检测不兼容性的功能(例如,如果您将字段添加到结构并尝试解码旧数据),但此自定义编码中缺少这些功能。

【讨论】:

    猜你喜欢
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 2011-10-31
    相关资源
    最近更新 更多