Какой предпочтительный способ кодирования «обнуляемого» поля в protobuf 2? - PullRequest
7 голосов
/ 08 февраля 2012

Я определяю сообщение ProtoBuf, в котором я хочу иметь «обнуляемое» поле - т.е. я хочу различать поле, имеющее значение и не имеющее значения. В качестве конкретного примера, скажем, у меня есть поля «x» и «y» для записи координат какого-либо объекта. Но в некоторых случаях координаты неизвестны. Следующее определение будет не работать, потому что если x или y не определены, то по умолчанию они равны нулю (что является допустимым значением):

message MyObject {
    optional float x = 1;
    optional float y = 2;
}

Один из вариантов - добавить запись логического поля независимо от того, известно значение соответствующего поля или нет. I.e.:

message MyObject {
    optional bool has_x = 1; // if false, then x is unknown.
    optional bool has_y = 2; // if false, then y is unknown.
    optional float x = 3; // should only be set if has_x==true.
    optional float y = 4; // should only be set if has_y==true.
}

Но это налагает некоторую дополнительную бухгалтерию - например, когда я устанавливаю значение поля x, я всегда должен не забывать также устанавливать has_x. Другим вариантом может быть использование значения списка с условием, что список всегда имеет длину 0 или 1:

message MyObject {
    repeated float x = 1; // should be empty or have exactly 1 element.
    repeated float y = 2; // should be empty or have exactly 1 element.
}

Но в этом случае определение кажется немного вводящим в заблуждение, и интерфейс не намного лучше.

Есть ли третий вариант, о котором я не подумал, что он лучше, чем эти два? Как вы справились с хранением пустых полей в protobuf?

Ответы [ 2 ]

4 голосов
/ 08 февраля 2012

Сообщения Protobuf 2 имеют встроенное понятие «пустые поля».Интерфейс C ++ содержит методы has_xxx и clear_xxx для проверки того, установлено ли поле и для сброса поля соответственно.

Эта функция предоставляется "бесплатно" из-за того, как поля кодируются в сообщениииспользуя «теги».Неустановленное поле просто «не присутствует» в закодированном сообщении.

Proto 3 не имеет этой функции , вместо этого вместо любого пропущенного поля устанавливается его значение по умолчанию .

1 голос
/ 08 февраля 2012

Имейте понятие NaN для каждого из типов, а затем используйте default (как показано ниже), чтобы установить его в качестве значения.Это будет использоваться, если для этого конкретного поля ничего не указано.

optional float x = 1 [default = -1];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...