Я определяю сообщение ProtoBuf, где я хочу иметь поле «nullable» - то есть, я хочу различать поле, имеющее значение и не имеющее значения. В качестве конкретного примера предположим, что у меня есть поля «x» и «y» для записи координат какого-либо объекта. Но в некоторых случаях координаты не известны. Следующее определение будет не работу, потому что если х или у не определены, то они по умолчанию к нулю (что является допустимым значением):Каков предпочтительный способ кодирования поля «nullable» в protobuf?
message MyObject {
optional float x = 1;
optional float y = 2;
}
Одним из вариантов было бы добавить логическое поле записи, является ли соответствующий значение поля известно или нет. Т.е .:
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.
}
Но это накладывает некоторую дополнительную бухгалтерию - например, когда заданное значение Х-FIELD, я должен всегда помнить также установить 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?
Вы уверены? В частности, если я кодирую сообщение и отправляю его по проводу, смогу ли я выделить объект, у которого его поле явно задано значением по умолчанию для объекта, чье поле никогда не было установлено ни на какое значение? См. Мой родственный вопрос: http://stackoverflow.com/questions/9168052/how-do-has-field-methods-relate-to-default-values-in-protobuf –
Да. Вы должны прочитать, как кодируются протоколы protobuf: http://code.google.com/apis/protocolbuffers/docs/encoding.html. Сообщения кодируются как серия пар ключ/значение (это то, что для идентификатора/тега для каждого поля). Исключенные поля просто отсутствуют в закодированном сообщении. Если у вас есть три поля: a, b и c с метками 1, 2 и 3 соответственно, и вы кодируете сообщение только с «a», установленным на «42», тогда закодированное сообщение будет содержать «поле (1) = 42 ", и ничего больше. – JesperE
Ответ JesperE может быть правдой в прошлом, но это определенно не так. – jordanbtucker