0

我有一个 protobuf 结构Data

.proto

message Data {
    uint64 ID = 1;
    uint32 GUID = 2;
}

在戈朗

b, err := proto.Marshal(&pb.Data{})
if err != nil {
    panic(err)
}
fmt.Println(len(b))

0长了!

无论 pb.Data 是什么,如何让 proto.Marshal 始终返回固定大小?

附言。

pb.Data 仅包含int64int32

4

2 回答 2

1

这里有两个问题

1) protobuf 对整数使用 varint 编码,因此大小取决于值,请参阅此链接

2)默认不发送零值字段,所以因为这两个整数都是零,所以连它们的字段标识都不会发送。我实际上不确定是否有发送零值查看文档的选项

如果将它们都设置为 1,则字节数将超过零,但长度仍不会固定,具体取决于值的范围

所以,一般来说,没有真正的方法在 protobuf 消息中强制执行固定大小

如果你想要固定长度的消息,你可能最好使用直接的 structs-on-the-wire 类型编码,但这对于语言互操作来说更难,因为它们都必须定义相同的消息,你会失去简单的消息迁移以及 protobuf 提供的所有很酷的东西。

Cap'n Proto可能有一个固定大小的结构的选项,但它们通常也会压缩,这将再次产生可变长度的消息。

如果您描述了您要最终解决的问题,我们可能会建议其他替代方案。

于 2018-10-23T17:27:33.423 回答
0

您正在调用len()一个字节数组。它将计算该数组中元素的数量,并将其返回。

如果您刚刚实例化了一个新的、空的、内部没有任何内容的 protobuf 指针对象,则封送字节数组将不会保存任何数据——这就是为什么您得到0.

我很不确定您希望它返回什么。你能用你想要的输出来澄清你的问题吗?我也许可以更好地回答你的问题。

于 2018-10-23T13:31:35.697 回答