Наследование в буферах протокола

Как обрабатывать наследование в 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;
}

2 ответа

Протокол Буферы не поддерживает наследование. Вместо этого рассмотрите возможность использования композиции:

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

Тем не менее, вы можете использовать хитрость, которая похожа на наследование, но которая является уродливым взломом, поэтому вы должны использовать ее только с осторожностью. Если вы определяете ваши типы сообщений, такие как:

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

Эти два типа совместимы, потому что Foo содержит надмножество полей Bar, Это означает, что если у вас есть закодированное сообщение одного типа, вы можете декодировать его как другой тип. Если вы попытаетесь расшифровать Bar как тип Foo, поле id не будет установлен (и получит значение по умолчанию). Если вы декодируете Foo как тип Bar, поле id будут игнорироваться (Обратите внимание, что это те же правила, которые применяются при добавлении новых полей в тип с течением времени.)

Вы можете использовать это для реализации чего-то вроде наследования, имея несколько типов, каждый из которых содержит копию полей "суперкласса". Однако есть несколько больших проблем с этим подходом:

  • Чтобы преобразовать объект сообщения типа Foo печатать BarВы должны сериализовать и повторно проанализировать; ты не можешь просто бросить. Это может быть неэффективно.
  • Очень трудно добавить новые поля в суперкласс, потому что вы должны убедиться, что добавили поле в каждый подкласс, и убедиться, что это не создает никаких конфликтов номеров полей.

См. Учебник Основы протокола буфера:

Не ищите средств, похожих на наследование классов, но буферные протоколы этого не делают.

Другие вопросы по тегам