2014-11-09 3 views
10

Я использую протокольные буферы, и все работает нормально. за исключением того, что тот факт, что я не понимаю - зачем мне пронумерованные теги в файле proto:Буферы протокола - уникальный пронумерованный тег - уточнение?

message SearchRequest { 
    required string query = 1; 
    optional int32 page_number = 2; 
    optional int32 result_per_page = 3; 
} 

Конечно, я прочитал docs:

Как вы можете видеть, каждый поле в определении сообщения имеет уникальный нумерованный тег . Эти теги используются для идентификации ваших полей в двоичном формате сообщения и не должны изменяться после использования вашего сообщения .

Я не понял, какая разница, если я его изменю. (Я буду создавать новую прото и собрать его - так почему не заботится)

Another article states that :

пронумерованные поля в определениях прото устраняет необходимость в версии проверки, которая является одной из явно указанных мотивов Разработка и реализация протокольных буферов. Как разработчик документации государств, протокол был разработан в рамках, чтобы избежать «гадкого код», как это для проверки версии протокола:

if (version == 3) { 
    ... 
} else if (version > 4) { 
    if (version == 5) { 
    ... 
    } 
    ... 
} 

Вопрос

Это только меня или это полностью непонятно?

позвольте мне задать его по-другому:

Если у меня есть прото файл, как вышеуказанный файл, а затем изменить его на:

message SearchRequest { 
    required string query = 3; //reversed order 
    optional int32 page_number = 2; 
    optional int32 result_per_page = 1; 
} 

Что волнует? Я повторно компилирую и добавляю файл (я делал это несколько раз за последнюю неделю).

Что мне не хватает? можете ли вы предоставить человеко-человеческое объяснение для этих пронумерованных тегов?

+1

'Что это за дело? На мой взгляд, вы делаете здесь замечательный момент. Если вам действительно не нужна обратная совместимость, тогда совершенно бесполезно явно указывать числа. Они могут (и для моего небольшого внутреннего проекта) автоматически создаваться. – gromit190

ответ

9

Пронумерованные теги используются для сопоставления полей при сериализации и десериализации данных.

Очевидно, что если вы измените схему нумерации и примените это изменение как к сериализатору, так и к десериализатору, проблем нет.

Если вы сохранили данные с первой схемой нумерации и загрузили их со второй, попробуйте загрузить query в result_per_page, и десериализация, скорее всего, не удастся.

Теперь, почему это полезно? Допустим, вам нужно добавить еще одно поле для данных, после того, схема уже используется:

message SearchRequest { 
    required string query = 1; 
    optional int32 page_number = 2; 
    optional int32 result_per_page = 3; 
    optional int32 new_data = 4; 
} 

Поскольку вы явно дать ему номер, ваш десериализатор по-прежнему иметь возможность загружать данные сериализованы с старый Схема нумерации, игнорируя десериализацию несуществующих данных.

+1

Теперь это понятно. было ли им так тяжело их пример? –

+0

@RoyiNamir очень хорошо объяснено https://developers.google.com/protocol-buffers/docs/encoding. См. Образец в качестве моего сообщения ниже – SMA

+0

@almasshaikh В ситуации, когда краткое (15 строк!) Не объясняет это достаточно просто вкратце - что заставляет меня идти на внутренние органы - ну, я нахожу это тревожным. –

2

Эти номера полей используются protobuf при кодировании и декодировании. См. here для более подробной информации.

Таким образом, каждое поле имеет тип провода, поэтому int32 имеет тип провода как 0, а номер вашего поля - 2, поэтому он будет закодирован как 0001 0000, т. Е. 10 в шестнадцатеричном виде.

И позже, когда его декодировано, его левое смещение на 1, что делает его как 001 0000, а последние три lsb определяет тип провода, то есть затем выдает его тип int field и rest решает, какое поле в прото, то есть 00010 2. Таким образом, поле 2 проводного типа 0 (int)

Смежные вопросы