协议缓冲区中的继承

Inheritance in protocol buffers

如何在 Google Protocol Buffers 3.0 中处理继承?

Java 等效代码:

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

Proto 等效代码是什么?

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

参见Protocol Buffer Basics教程:

Don't go looking for facilities similar to class inheritance, though – protocol buffers don't do that.

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

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

不过,话虽如此,您可以使用一种类似于继承的技巧 -- 但这是一种丑陋的 hack,因此您应该谨慎使用它。如果您将消息类型定义为:

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

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

您可以使用它来实现类似继承的东西,方法是让几种类型都包含 "superclass" 字段的副本。但是,这种方法有几个大问题:

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