我的任务是构建一个基于Google Protocol Buffer的对象,该对象可以使用所有消息/命令详细信息将单个消息传递给RabbitMQ。我使用了概念"扩展"用于包装单个消息下的所有字段。但我无法在扩展部分下声明所需的数据字段。我的消息格式如下。
message A
{
message B
{
extension 100 to max;
required int32 a = 1;
required int32 b = 2;
}
message C
{
extend B
{
required string name = 100;
}
}
repeated A messageA = 1;
};
我收到错误消息扩展名不能包含必填字段。
Commands.proto:36:34: Message extensions cannot have required fields.
如果我将扩展部分改为
message C
{
extend B
{
optional string name = 100;
}
}
然后它工作正常。我还提到了一些解决方案的链接http://forum.choosemuse.com/forum/developer-forum/1251-protobuf-2-6-0-required 这告诉我必须使用升级protoc版本。目前我正在使用protobuf 2.6.1。我还尝试使用protobuf 3.0.0 alpha版本。但我找不到任何改进:(。请帮我解决这个错误,请纠正我,如果我有任何错误的方式。
答案 0 :(得分:0)
这里的语法令人困惑(这是我的错)。扩展不像继承。扩展本质上为现有类型添加了一个新字段,而无需编辑原始类型的定义;它没有声明扩展类型和词法上包含扩展名的类型之间的任何关系。
在您的示例中,您声明类型A.B
有一个名为A.C.name
的附加字段,其类型为string
。请注意,name
在C
内的行为类似于静态常量 - 它对C
本身没有影响。你可以很容易地在C之外定义它:
message A
{
message B
{
extension 100 to max;
required int32 a = 1;
required int32 b = 2;
}
extend B
{
required string name = 100;
}
message C
{
}
repeated A messageA = 1;
};
我在这里写的内容和你写的内容之间的唯一的区别在于我写的内容,你将扩展称为A.name
,而你所写的内容则是将是A.C.name
。在这两种情况下,类型C
实际上没有字段,与B
没有关系。唯一的区别是名称的范围。再次,把它想象成静态常量:如果你用C ++编写:
class Foo {
static const int I = 1;
};
Foo
与I
之间没有任何关系,只是I
的范围是Foo
。 Protobufs中的扩展就是这样。
无论如何,现在应该清楚为什么不需要扩展:这意味着在name
中需要B
。也就是说,如果没有设置扩展字段B
,则无法序列化name
。允许这种约束是没有意义的:如果需要一个字段,它应该直接在需要它的消息中声明,而不是在其他地方声明。
Protobuf 3实际上是从语言中删除扩展名,因为太混乱了。所以,你可能不应该在新代码中使用它们。
答案 1 :(得分:0)
关于扩展消息中的必填字段,我根据我在问题http://forum.choosemuse.com/forum/developer-forum/1251-protobuf-2-6-0-required中使用Muse_v2.proto所述的解决方案链接,尝试使用protoc 3.0进行冲突Message extensions cannot have required fields
。但似乎我们也无法在proto3中的扩展消息中获得必填字段。
我用“syntax =”proto3“;”获得的错误如,
Commands.proto: Required fields are not allowed in proto3.
Commands.proto: Extension ranges are not allowed in proto3.
Commands.proto: The first enum value must be zero in proto3.
Commands.proto: Extensions in proto3 are only allowed for defining options.
Commands.proto:124:34: Explicit 'optional' labels are disallowed in the Proto3 syntax. To define 'optional' fields in Proto3, simply remove the 'optional' label, as fields are 'optional' by default.
所以我发现的是:
似乎所有这些选项都在开发中。只有proto2完全包含了所有可交付的概念。
对我来说,某些需求的澄清可能会有所帮助。如果我在这里弄错了,请纠正我。