You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中解码带自定义类型头部的Protobuf消息的符合语言习惯的实现方案咨询

Go语言中解码带自定义类型头部的Protobuf消息的符合语言习惯的实现方案咨询

我正在尝试为我们内部的Protobuf框架实现一个Go语言的扩展。我们已经在C、Python和其他几种语言的多个服务中实现了这个框架,所以修改消息格式是不可能的。我想找到最符合Go语言习惯(同时最省心)的实现方式。

我们的做法是给所有Protobuf消息前面加上一个小头部,其中一个字段表示消息类型。在这个框架里编码消息其实很简单:

const (
    MessageEmpty = iota
    Message1
    Message2
)

func Encode(msgType byte, msg proto.Message) ([]byte, error) {
    buf, err := proto.Marshal(msg)
    if err != nil {
        return nil, err
    }

    hdr := Header {
        msgtype: msgType,
    }

    out := new(bytes.Buffer)
    err = binary.Write(out, binary.BigEndian, hdr)
    if err != nil {
        return nil, err
    }
    
    out.Grow(len(buf))
    _, err = out.Write(buf)
    if err != nil {
        return nil, err
    }

    return out.Bytes(), nil
}

我还没彻底测试这段代码,但初看起来是对的。不过我现在遇到的问题是编写Decode()函数。我想实现的逻辑大概是这样的:

func Decode(pkt []byte) (proto.Message, error) {
    hdr := Header{}
    buf := bytes.NewBuffer(pkt)
    ret := proto.Message()

    err := binary.Read(buf, binary.BigEndian, &hdr)
    if err != nil {
        return nil, err
    }
    
    msg := buf.Bytes()
    switch hdr.msgType {
    case Message1:
        pbmsg := myproto.FirstMessage{}
        err = proto.Unmarshal(msg, &pbmsg)
        ret = &pbmsg
    case Message2:
    }

    if err != nil {
        return nil, err
    }

    return ret, nil
}

但这段代码编译不通过。而且接下来我还会遇到一个问题:当我得到消息后,如何在运行时判断它的类型?(我想过可以把msgType字段也作为返回值之一)

欢迎任何建议和指导。

备注:内容来源于stack exchange,提问作者Ken P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:58:05