在协议缓冲区中定义字典

use*_*786 5 dictionary protocol-buffers

我是协议缓冲区和C++的新手,所以这可能是一个基本问题,但我没有找到答案的运气.基本上,我想要在我的.proto文件中定义的字典的功能,如enum.我正在使用协议缓冲区来发送数据,我想定义单位及其各自的名称.一个enum允许我定义单位,但我不知道如何将人类可读的字符串映射到那个.

作为我的意思的一个例子,该.proto文件可能看起来像:

message DataPack {
    // obviously not valid, but something like this
    dict UnitType {
        KmPerHour = "km/h";
        MiPerHour = "mph";
    }

    required int id = 1;
    repeated DataPoint pt = 2;

    message DataPoint {
        required int id = 1;
        required int value = 2;
        optional UnitType theunit = 3;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后有类似创建/处理消息的东西:

// construct
DataPack pack;
pack->set_id(123);
DataPack::DataPoint pt = pack.add_point();
pt->set_id(456);
pt->set_value(789);
pt->set_unit(DataPack::UnitType::KmPerHour);

// read values
DataPack::UnitType theunit = pt.unit();
cout << theunit.name << endl; // print "km/h"
Run Code Online (Sandbox Code Playgroud)

我可以enum用单位名称定义一个并编写一个函数来将它们映射到接收端的字符串,但是将它们定义在同一个位置会更有意义,并且该解决方案看起来太复杂了(至少对某些人来说)谁最近被Python的便利所破坏了.有没有更简单的方法来实现这一目标?

jpa*_*jpa 6

您可以使用自定义选项将字符串与每个枚举成员相关联:https: //developers.google.com/protocol-buffers/docs/proto#options

它会在.proto中看起来像这样:

extend google.protobuf.FieldOptions {
  optional string name = 12345;
}

enum UnitType {
    KmPerHour = 1 [(name) = "km/h"];
    MiPerHour = 2 [(name) = "mph"];
}
Run Code Online (Sandbox Code Playgroud)

但请注意,某些第三方protobuf库不了解这些选项.

  • 这看起来正是我想要的,尽管我认为我需要使用“EnumValueOptions”而不是“FieldOptions”。谢谢。不过,我在使用 C++ 访问结果时遇到了麻烦 - 您能否给出一个实际检索值的简短示例? (2认同)
  • 你为什么protobuf3团队省略了保留字符串或int常量的能力??这是使用 .proto 文件的最基本的功能,也是最明显的特性——拥有一个用于跨平台消息模式的源文件。啊! (2认同)

Noe*_*Yap 5

在 proto3 中,它是:

extend google.protobuf.EnumValueOptions {
  string name = 12345;
}

enum UnitType {
  KM_PER_HOUR = 0 [(name) = "km/h"];
  MI_PER_HOUR = 1 [(name) = "mph"];
}
Run Code Online (Sandbox Code Playgroud)

并在 Java 中访问它:

UnitType.KM_PER_HOUR.getValueDescriptor().getOptions().getExtension(MyOuterClass.name);
Run Code Online (Sandbox Code Playgroud)