douzhangkui2467 2019-02-19 12:37
浏览 78
已采纳

寄存器类型后,Gob解码无法解码接口

I have these types defined:

func init() {
    gob.RegisterName("MyMessageHeader", MyMessageHeader{})
    gob.RegisterName("OtherMsg", OtherMsg{})
}

//
// Messages
//

type MyMessageHeader struct {
    MessageId InstanceIdType
    OtherId   uint64
}

type MyMessage interface {
    Id() *MyMessageHeader
}

type otherStruct struct {
    X uint8
    Y uint8
}
type OtherMsg struct {
    MyMessageHeader
    OtherField *otherStruct
}


func (m *OtherMsg) Id() *MyMessageHeader {
    return &m.MyMessageHeader
}

func MarshalMessage(m MyMessage) ([]byte, error) {
    var buff bytes.Buffer
    encoder := gob.NewEncoder(&buff)
    if err := encoder.Encode(&m); err != nil {
        return nil, errors.Newf("Could not marshal message: %v", err)
    }
    return buff.Bytes(), nil
}

func UnmarshalMessage(buf []byte) (MyMessage, error) {
    var msg MyMessage
    decoder := gob.NewDecoder(bytes.NewReader(buf))
    if err := decoder.Decode(&msg); err != nil {
        return nil, errors.Newf("Could not decode my message: %v", err)
    }
    return msg, nil
}

When I try to use UnmarshalMessage I got the error gob: OtherMsg is not assignable to type MyMessage. I have no difference with the usage in the go examples for encoding and decoding an interface. What am I doing wrong?

  • 写回答

1条回答 默认 最新

  • doureng6738 2019-02-19 13:55
    关注

    The error message says:

    gob: OtherMsg is not assignable to type MyMessage

    Which is true. MyMessage is an interface which requires implementing types to have a method:

    Id() *MyMessageHeader
    

    A value of type OtherMsg does not have such method in its method set, only a pointer to it, that is a value of type *OtherMsg (because OtherMsg.Id() has pointer receiver).

    To make it work, register a value of type *OtherMsg:

    gob.RegisterName("OtherMsg", &OtherMsg{})
    

    Or simply:

    gob.Register(&OtherMsg{})
    

    See a working example on the Go Playground:

    func init() {
        gob.Register(&OtherMsg{})
    }
    
    func main() {
        var m MyMessage = &OtherMsg{
            MyMessageHeader: MyMessageHeader{
                MessageId: 1,
                OtherId:   2,
            },
            OtherField: "othervalue",
        }
    
        data, err := MarshalMessage(m)
        if err != nil {
            panic(err)
        }
    
        m2, err := UnmarshalMessage(data)
        if err != nil {
            panic(err)
        }
        fmt.Printf("%+v
    ", m2)
    }
    

    Output (try it on the Go Playground):

    &{MyMessageHeader:{MessageId:1 OtherId:2} OtherField:othervalue}
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 求快手直播间榜单匿名采集ID用户名简单能学会的
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历