Encoding 如何对空字符串进行编码/解码

Encoding 如何对空字符串进行编码/解码,encoding,character-encoding,go,gob,Encoding,Character Encoding,Go,Gob,我在我的项目中使用GOB编码,经过长时间的斗争,我发现空字符串没有正确编码/解码。在我的代码中,我使用一个errormessage(字符串)来报告任何问题,这个errormessage大部分时间是空的。如果我对一个空字符串进行编码,它就会变成空字符串,这就给了我一个解码问题。我不想改变编码/解码,因为这些部分使用最多。 我如何告诉Go如何编码/解码空字符串 例如: 工作代码。 无法工作的代码。问题不在于编码/gob模块,而是您为Msg声明的自定义封送二进制/解封二进制方法,该方法无法正确往返空字

我在我的项目中使用GOB编码,经过长时间的斗争,我发现空字符串没有正确编码/解码。在我的代码中,我使用一个errormessage(字符串)来报告任何问题,这个errormessage大部分时间是空的。如果我对一个空字符串进行编码,它就会变成空字符串,这就给了我一个解码问题。我不想改变编码/解码,因为这些部分使用最多。 我如何告诉Go如何编码/解码空字符串

例如: 工作代码。
无法工作的代码。

问题不在于
编码/gob
模块,而是您为
Msg
声明的自定义
封送二进制
/
解封二进制
方法,该方法无法正确往返空字符串。这里有两种方法:

  • 摆脱
    MarshalBinary
    /
    UnmarshalBinary
    方法,并依赖GOB的默认结构编码。仅此更改是不够的,因为结构的字段没有导出。如果您愿意导出字段,那么这是最简单的选项:

  • 使用可以正确往返空字符串的编码。一个简单的选择是使用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)
    }
    
    您可以在此处尝试此示例:


  • 第一个选项显然更简单,但是如果您的实际示例稍微复杂一点,那么第二个选项可能会有用。但要小心使用自定义编码器:GOB包含一些用于检测不兼容的功能(例如,如果向结构中添加字段并尝试解码旧数据),这些功能在此自定义编码中缺失。

    查看示例,问题在于您的自定义
    MarshalBinary
    /
    UnmarshalBinary
    方法,而不是gob。如果您导出结构中的字段(使其大写)并只使用默认的gob编组,您的示例就可以运行了。@James Henstridge谢谢,它可以完美地运行。张贴一个答案,这样我就可以把你标记为答案。顺便说一句,必须有人更新文档,因为我不知道大写字段会解决我第一次遇到的另一个问题。