What's the preferred way to encode a “nullable” field in protobuf 2?

好久不见. 提交于 2019-12-04 11:18:40

问题


I am defining a ProtoBuf message where I want to have a "nullable" field -- i.e., I want to distinguish between the field having a value and not having a value. As a concrete example, let's say I have "x" and "y" fields to record the coordinates of some object. But in some cases, the coordinates are not known. The following definition will not work, because if x or y are unspecified, then they default to zero (which is a valid value):

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

One option would be to add a boolean field recording whether the corresponding field's value is known or not. 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.
}

But this imposes some extra book-keeping -- e.g., when I set the x field's value, I must always remember to also set has_x. Another option would be to use a list value, with the convention that the list always has either length 0 or length 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.
}

But in this case, the definition seems a bit misleading, and the interface isn't much better.

Is there a third option that I haven't thought of that's better than these two? How have you dealt with storing nullable fields in protobuf?


回答1:


Protobuf 2 messages have a built-in notion of "nullable fields". The C++ interface contains methods has_xxx and clear_xxx to check if the field has been set and to unset the field, respectively.

This feature comes "for free" due to the way fields are encoded in message using "tags". An unset field is simply "not present" in the encoded message.

Proto 3 does not have this feature, instead setting any missing field to its default value.




回答2:


Have a notion of NaN for each of the types and then use default (as shown below) to set it as the value. This will be used if nothing is specified for that particular field.

optional float x = 1 [default = -1];


来源:https://stackoverflow.com/questions/9184215/whats-the-preferred-way-to-encode-a-nullable-field-in-protobuf-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!