Java 协议缓冲区中的继承

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41243168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:15:06  来源:igfitidea点击:

Inheritance in protocol buffers

javaprotocol-buffersprotocol-buffers-3

提问by Vivek Sinha

How to handle inheritance in Google Protocol Buffers 3.0?

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

Java equivalent code:

Java等效代码:

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

What would be Proto equivalent code?

什么是 Proto 等效代码?

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

采纳答案by Kenton Varda

Protocol Buffers does not support inheritance. Instead, consider using composition:

Protocol Buffers 不支持继承。相反,请考虑使用组合:

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

However, that said, there is a trick you can use which is like inheritance -- but which is an ugly hack, so you should only use it with care. If you define your message types like:

但是,也就是说,您可以使用一个类似于继承的技巧——但这是一个丑陋的技巧,因此您应该谨慎使用它。如果您定义消息类型,例如:

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

These two types are compatible, because Foocontains a superset of the fields of Bar. This means if you have an encoded message of one type, you can decode it as the other type. If you try to decode a Baras type Foo, the field idwill not be set (and will get its default value). If you decode a Fooas type Bar, the field idwill be ignored. (Notice that these are the same rules that apply when adding new fields to a type over time.)

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

You can possibly use this to implement something like inheritance, by having several types all of which contain a copy of the fields of the "superclass". However, there are a couple big problems with this approach:

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

  • To convert a message object of type Footo type Bar, you have to serialize and re-parse; you can't just cast. This can be inefficient.
  • It's very hard to add new fields to the superclass, because you have to make sure to add the field to every subclass and have to make sure that this doesn't create any field number conflicts.
  • 要将 type 的消息对象转换Foo为 type Bar,您必须序列化和重新解析;你不能只是投射。这可能是低效的。
  • 向超类添加新字段非常困难,因为您必须确保将字段添加到每个子类,并且必须确保这不会造成任何字段编号冲突。

回答by Andy Turner

See the Protocol Buffer Basicstutorial:

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

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

不过,不要去寻找类似于类继承的工具——协议缓冲区不会那样做。