如何在没有模式的情况下从原始语音消息中提取字段

根据这个问题protoreflect包提供了用于访问protobuf消息的“未知字段”的API,但是如果没有任何现有的架构,我看不到任何使用它的方法。基本上,我想执行“弱解码”,类似于JSON unmarshaller在输出类型时执行的操作。map[string]interface{}

文档中的示例如下所示:

err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m)

其中 是输入字节切片,是输出消息,需要以某种方式进行初始化,如您在此处所示。我在想dynamicpb可以用于这个目的,但是如果没有现有的MessageDescriptor,它看起来是不可能的,这就是我陷入困境的地方......bm


红糖糍粑
浏览 62回答 1
1回答

慕妹3146593

我能够使用低级protowire封装实现这一目标。下面是一个完整的示例,其中我提取了两个类型的字段(在原始架构中恰好分配了字段编号&nbsp;4 和 5):uint64import "google.golang.org/protobuf/encoding/protowire"func getData(src []byte) (creationTime, expiryTime uint64, err error) {&nbsp; &nbsp; remaining := src&nbsp; &nbsp; for len(remaining) > 0 {&nbsp; &nbsp; &nbsp; &nbsp; fieldNum, wireType, n := protowire.ConsumeTag(remaining)&nbsp; &nbsp; &nbsp; &nbsp; if n < 0 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0, 0, fmt.Errorf("failed to consume tag: %w", protowire.ParseError(n))&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; remaining = remaining[n:]&nbsp; &nbsp; &nbsp; &nbsp; switch fieldNum {&nbsp; &nbsp; &nbsp; &nbsp; case 4: // Expiry time&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if wireType != protowire.VarintType {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0, 0, fmt.Errorf("unexpected type for expiry time field: %d", wireType)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; expiryTime, n = protowire.ConsumeVarint(remaining)&nbsp; &nbsp; &nbsp; &nbsp; case 5: // Creation time&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if wireType != protowire.VarintType {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0, 0, fmt.Errorf("unexpected type for creation time field: %d", wireType)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; creationTime, n = protowire.ConsumeVarint(remaining)&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n = protowire.ConsumeFieldValue(fieldNum, wireType, remaining)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if n < 0 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0, 0, fmt.Errorf("failed to consume value for field %d: %w", fieldNum, protowire.ParseError(n))&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; remaining = remaining[n:]&nbsp; &nbsp; }&nbsp; &nbsp; return}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go