Почему в proto3 нет пользовательских значений по умолчанию?
Протокольная версия буферов протокола позволяет указывать значения по умолчанию для элементов сообщения:
optional double scaling_factor = 3 [default = 1.0];
Почему это больше невозможно в proto3? Я считаю, что это полезная функция, позволяющая сохранять дополнительные байты в сети без необходимости написания кода-обертки.
2 ответа
Насколько я понимаю, proto3 больше не позволяет обнаруживать наличие полей и больше не поддерживает ненулевые значения по умолчанию, потому что это облегчает реализацию protobufs в виде "простых старых структур" на разных языках без необходимости генерировать методы доступа. Это считается облегчением использования Protobuf на этих языках.
(Лично я считаю, что языки, в которых отсутствуют методы доступа и свойства, не очень хорошие языки, и их не следует разрабатывать с помощью protobuf, но это больше не мой проект.)
This is a work around instead of a direct answer to your question, but I've found myself using wrappers.proto optional values and then setting the default value myself programatically when I absolutely must know if this was a default value or a value that was explicitly set.
Not optimal that your code has to enforce the value instead of the generated code itself, but if you own both sides, at least it's a viable alternative versus having no idea if the value was the default or explicity set as such, especially when looking at a bool set to false.
I am unclear how this affects bytes on the wire. For the instances where I've used it, message length was not a design constraint.
Proto File
import "google/protobuf/wrappers.proto";
google.protobuf.BoolValue optional_bool = 1;
Java code
//load or receive message here
if( !message.hasOptionalBool() )
message.setOptionalBool( BoolValue.newBuilder().setValue( true ) );
В моем автоматически сгенерированном файле.pb.cc я вижу несколько таких мест:
if (this->myint() != 0) {
и немногие так:
myint_ = 0;
Итак, почему бы не включить значение по умолчанию и генерировать
static ::google::protobuf::int32 myint_defaultvalue = 5;
...
if (this->myint() != myint_defaultvalue) {
...
...
myint_ = myint_defaultvalue;
...
вместо?