协议缓冲区中的继承

如何在Google协议缓冲区3.0中处理继承?

Java 等效代码:

public class Bar {
    String name;
}
public class Foo extends Bar {
    String id;
}

什么是原始等效代码?

message Bar {
    string name = 1;
}
message Foo {
    string id = 2;
}

答案 1

协议缓冲区不支持继承。相反,请考虑使用组合:

message Foo {
  Bar bar = 1;
  string id = 2;
}

但是,话虽如此,您可以使用一种技巧,就像继承一样 - 但这是一个丑陋的黑客,所以您应该谨慎使用它。如果您定义消息类型,例如:

message Bar {
  string name = 1;
}
message Foo {
  string name = 1;
  string id = 2;
}

这两种类型是兼容的,因为 包含 的字段的超集。这意味着,如果您有一种类型的编码消息,则可以将其解码为另一种类型。如果您尝试解码为类型,则不会设置该字段(并将获取其默认值)。如果将 a 解码为 类型,则该字段将被忽略。(请注意,这些规则与随时间推移向类型添加新字段时适用的规则相同。FooBarBarFooidFooBarid

您可以使用它来实现类似继承的内容,方法是拥有几种类型,所有这些类型都包含“超类”字段的副本。但是,这种方法存在几个大问题:

  • 要将类型的消息对象转换为 类型,您必须序列化并重新解析;你不能只是投掷。这可能效率低下。FooBar
  • 向超类添加新字段非常困难,因为您必须确保将字段添加到每个子类,并且必须确保这不会产生任何字段编号冲突。

答案 2

请参阅协议缓冲区基础知识教程:

但是,不要去寻找类似于类继承的工具 - 协议缓冲区不会这样做。


推荐