Подтвердить что ты не робот

Как методы has_field() относятся к значениям по умолчанию в protobuf?

Я пытаюсь определить взаимосвязь между значениями по умолчанию и методами has_foo(), которые объявлены в различных программных интерфейсах. В частности, я пытаюсь определить, при каких обстоятельствах (если они есть) вы можете "рассказать разницу" между полем, явно установленным значением по умолчанию, и неустановленным значением.

  • Если я явно установил поле (например, "Bar.foo" ) в значение по умолчанию (например, ноль), то Bar:: has_foo() гарантировал возврат true для этой структуры данных? (Это, по-видимому, верно для сгенерированного кода на С++, но это не значит, что он гарантирован.) Если это так, тогда можно различать явно заданное значение по умолчанию и значение unset перед сериализацией.

  • Если я явно устанавливаю поле по умолчанию (например, ноль), а затем сериализует этот объект и отправляет его по проводу, будет ли оно отправлено или нет? Если это не так, то ясно, что любой код, который получает этот объект, не может различать явно заданное значение по умолчанию и неустановленное значение. Я., невозможно будет отличить эти два случая после сериализации - Bar:: has_foo() вернет false в обоих случаях.

Если невозможно определить разницу, каков рекомендуемый метод кодирования поля protobuf, если я хочу кодировать "нулевое" необязательное значение? Пара вариантов приходит на ум, но не кажется большим: (a) добавить дополнительное логическое поле, которое записывает, установлено ли поле или нет, или (b) использовать "повторное" поле, даже если я семантически хочу дополнительное поле - таким образом, я могу определить разницу между значением no (length-zero list) или заданным значением (длина-один список).

4b9b3361

Ответ 1

Для синтаксиса "proto2", а не "proto3", применяется следующее:

Понятие заданного или не заданного поля - это ключевое свойство ядра Protobuf. Если вы установите поле в значение (любое значение), то соответствующий метод has_xxx должен вернуть значение true, иначе у вас есть ошибка в API.

Если вы не установите поле и не сериализуете сообщение, для этого поля не будет отправлено никакого значения. Принимающая сторона будет анализировать сообщение, обнаруживать, какие значения включены, и устанавливать соответствующие значения "has_xxx".

Именно то, как это реализовано в проводном формате, описано здесь: http://code.google.com/apis/protocolbuffers/docs/encoding.html. Краткая версия состоит в том, что сообщение закодировано как последовательность пар ключ-значение, и только поля, которые явно заданы, включены в закодированное сообщение.

Значения по умолчанию включаются только в том случае, если вы пытаетесь прочитать снятое поле.