Почему Protobuf 3 сделал все поля в сообщениях необязательными?

15

Синтаксис 3 protobuf сделал все поля необязательными, исключая ключевые слова requiredи optionalиз предыдущего синтаксиса proto2. Читая некоторые комментарии разработчиков, кажется, что это было сделано для улучшения прямой / обратной двоичной совместимости.

Но для меня это может быть реализовано путем простого управления версиями имен пакетов, скажем, com.example.messages.v1а затем позволить клиентам реализовывать десериализаторы, которые они понимают. В то же время он удаляет некоторые контракты, указанные как тип, которые полезны с точки зрения разработки программного обеспечения. Например, если у меня есть

message Location {
   double latitude = 1;
   double longitude = 2;
}

В proto3 можно создать половинную резервную копию, но она полностью действительна, Locationесли не предоставить одно из обязательных полей.

Разве это не большой недостаток при создании формата сериализации на основе схемы для обмена данными между клиентами? Не хуже ли передать дополнительный код проверки каждому клиенту, проверяя, что все обязательные поля имеют допустимые значения?

tonicebrian
источник
leanpub.com/esversioning
VoiceOfUnreason

Ответы:

13

Proto3 вносит ряд изменений, направленных (насколько я понимаю), чтобы сделать его гораздо более удобным для использования в кроссплатформенных сценариях. Явное отслеживание «назначенных» и «не назначенных, но сообщающих о значении по умолчанию» может быть очень трудным для реализации на некоторых целевых платформах, а также может привести к путанице в использовании. Таким образом, proto3 использует гораздо более простой подход:

  • неявное значение по умолчанию является естественным нулевое значение (число / перечислений), ложные (булевы) или пустая строка (строки)
  • допускается только неявное значение по умолчанию; другие значения по умолчанию не допускаются
  • если поле имеет это значение по умолчанию, оно не сериализуется; не имеет значения, был ли он назначен явно в ноль / ложь / пустая строка против никогда не назначен
  • из-за этого не существует понятия «требуется», поскольку «явно назначенное нулевое значение» и «никогда не назначаемое значение» выглядят одинаково

В proto3 можно создать полукабельное, но совершенно корректное местоположение, не предоставляя одно из обязательных полей.

Другое значение: ноль. Тот факт , что вы не явно назначить его к нулю спорно. Является ли это желательным или нет, зависит от вас, но для меня это имеет смысл, и именно так много «инициализации нового объекта / структуры» работает на широком спектре платформ.

Не хуже ли передать дополнительный код проверки каждому клиенту, проверяя, что все обязательные поля имеют допустимые значения?

Там нет ничего, чтобы проверить! Компоновка - это именно то, что было бы, если бы нулевое значение было назначено явно. Если это законно, это законно. Если это незаконно (потому что ноль не имеет смысла для вас), это незаконно; но это было бы незаконно, было ли это явным или неявным. Количество проверок не меняется.

Разве это не большой недостаток при создании формата сериализации на основе схемы для обмена данными между клиентами?

Не обычно, нет ... тем более что версия схемы является явной. Если вы хотите использовать proto2: используйте proto2. Ничто не меняется автоматически.

Марк Гравелл
источник
Интересно, что их покупает «только натуральный ноль по умолчанию», так как protobuf не может быть использован без какой-либо схемы. Обеспечение согласованных значений по умолчанию не намного сложнее, чем обеспечение согласованных схем.
CodesInChaos
1
@CodesInChaos, что интересно, потому что я делал protobuf без схемы для ... ну, навсегда :) в protobuf-net, ожидается, что большинство пользователей будут без кода и без схемы. И что интересно (по крайней мере, для меня), большинство стратегий по умолчанию «будь проще, тупой», которые использует protobuf-net, точно такие же, как и выбранные для proto3. Я не собираюсь утверждать, что это подтверждает мои случайные партизанские решения, но ... это полностью
Марк Гравелл
Я считаю класс C # своего рода схемой, и вы, безусловно, можете указать значения по умолчанию через атрибуты. Сравните это, например, с msgpack или json, которые могут создать значимую структуру данных без какой-либо схемы.
CodesInChaos
@CodesInChaos согласился и отметил - и да, protobuf-net будет соблюдать и уважать любые такие заявления
Марк Грэвелл