编码“可空"的首选方法是什么?protobuf 2 中的字段? [英] What's the preferred way to encode a "nullable" field in protobuf 2?

查看:61
本文介绍了编码“可空"的首选方法是什么?protobuf 2 中的字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在定义一个 ProtoBuf 消息,其中我想要一个可为空"字段——即,我想区分具有值的字段和没有值的字段.作为一个具体的例子,假设我有x"和y"字段来记录某个对象的坐标.但在某些情况下,坐标是未知的.以下定义将不起作用,因为如果未指定 x 或 y,则它们默认为零(这是一个有效值):

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.
}

但这会强加一些额外的簿记——例如,当我设置 x 字段的值时,我必须始终记住还要设置 has_x.另一种选择是使用列表值,约定列表的长度总是为 0 或长度为 1:

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.

有没有比这两个更好的第三种选择?您如何处理在 protobuf 中存储可空字段的问题?

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?

推荐答案

Protobuf 2 消息具有可空字段"的内置概念.C++ 接口包含方法 has_xxxclear_xxx 分别用于检查字段是否已设置和取消设置字段.

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 没有此功能,而是将任何缺失的字段设置为 其默认值.

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

这篇关于编码“可空"的首选方法是什么?protobuf 2 中的字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆