前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >【Protobuf协议】002-标准类型、默认值、枚举、使用费其他消息类型

【Protobuf协议】002-标准类型、默认值、枚举、使用费其他消息类型

作者头像
訾博ZiBo
发布2025-01-06 17:22:17
发布2025-01-06 17:22:17
10800
代码可运行
举报
运行总次数:0
代码可运行

三、标准类型

其他语言见官方文档:https://developers.google.com/protocol-buffers/docs/javatutorial#scalar

.proto Type

Notes

Java Type

double

double

float

float

int32

使用可变长编码,编码负数的效率很低——如果你的字段可能有负数,使用sint32代替

int

int64

使用可变长编码,编码负数的效率很低——如果你的字段可能有负数,使用sint64代替

long

uint32

使用可变长度编码

int[1]

uint64

使用可变长度编码

long[1]

sint32

使用可变长编码,带符号的int值。它们比普通int32编码负数更有效

int

sint64

使用可变长编码,带符号的int值。它们比普通int64编码负数更有效

long

fixed32

总是4个字节,如果值经常大于2的28次方,则比uint32更有效

int[1]

fixed64

总是8个字节,如果值经常大于2的56次方,则比uint64更有效

long[1]

sfixed32

总是4个字节

int

sfixed64

总是8个字节

long

bool

boolean

string

字符串必须始终包含UTF-8编码或7位ASCII文本,且长度不能超过2的32次方

String

bytes

可以包含不超过2的32次方的任意字节序列

ByteString

四、默认值

在解析消息时,如果编码的消息不包含特定的单个元素,则解析对象中的相应字段将设置为该字段的默认值;

类型

默认值

string

空字符串

bytes

空字符

bool

false

num

0

enums

对于枚举,默认值是第一个定义的枚举值,该值必须为0

message

与对应编程语言有关

重复字段

重复字段的默认值为空(通常在适当的语言中为空列表)

请注意,对于标量消息字段(标准类型字段),一旦消息被解析,就无法判断字段是显式设置为默认值(例如,是否将布尔值设置为 false),还是根本没有设置,在定义消息类型时应该牢记这一点。例如,如果您不希望某些行为在默认情况下也发生,那么就不要设置一个布尔值,该布尔值在设置为 false 时可以开启某些行为。还要注意,如果将标量消息字段设置为默认值,则该值将不会在连接上序列化。

五、枚举

1、简单使用

限定字段的值在一个列表中;

在定义消息类型时,您可能希望它的某个字段只有一个预定义的值列表。比如某件商品几种确定的尺码,您可以非常简单地做到这一点,方法是在消息定义中为每个可能的值添加一个带常量的枚举。

代码语言:javascript
代码运行次数:0
复制
message SearchRequest {
    string query = 1;
    int32 page_number = 2;
    int32 result_per_page = 3;
    enum Corpus {
        UNIVERSAL = 0;
        WEB = 1;
        IMAGES = 2;
        LOCAL = 3;
        NEWS = 4;
        PRODUCTS = 5;
        VIDEO = 6;
    }
    Corpus corpus = 4;
}

如您所见,Corpus enum 的第一个常量映射为0,每个 enum 定义必须包含一个常量,该常量映射为0作为它的第一个元素。这是因为:

  • 必须有一个0值,以便我们可以使用0作为数值默认值;
  • 0值必须是第一个元素,以便与 proto2语义兼容,其中第一个枚举值总是默认值。

枚举数常数必须在32位整数的范围内。由于枚举值在线路上使用变容编码,因此负值效率低,因此不推荐使用。可以在消息定义中定义枚举(如上面的例子所示) ,也可以在消息定义中重用这些枚举。 如果在.proto文件中使用枚举,在使用protobuf编译器编译之后,会生成C++、Java对应的枚举,Python有一个特殊的EnumDescriptor类; 警告:生成的代码可能会受到特定于语言的枚举数量限制;

2、别名

假如你需要给不同的枚举常量设置为相同的值,那么你必须设置别名,这样做必须将 allow_alias 选项设置为 true ,否则会报错!

代码语言:javascript
代码运行次数:0
复制
message MyMessage1 {
  enum EnumAllowingAlias {
    option allow_alias = true;
    UNKNOWN = 0;
    STARTED = 1;
    RUNNING = 1;
  }
}
message MyMessage2 {
  enum EnumNotAllowingAlias {
    UNKNOWN = 0;
    STARTED = 1;
    // RUNNING = 1;  // Uncommenting this line will cause a compile error inside Google and a warning message outside.
  }
}

3、预留值

与预留字段类似;

代码语言:javascript
代码运行次数:0
复制
enum Foo {
    reserved 2, 15, 9 to 11, 40 to max;
    reserved "FOO", "BAR";
}

注意,不能在同一保留语句中混合字段名和数值。

六、使用其他消息类型

1、简单例子

代码语言:javascript
代码运行次数:0
复制
message SearchResponse {
    repeated Result results = 1;
}

message Result {
    string url = 1;
    string title = 2;
    repeated string snippets = 3;
}

2、导入定义*

这个部分不太明白!!!

注意,这个特性在Java中是不可用的!

上面的例子中,Result消息和SearchResponse消息定义在同一个文件中,可以直接使用,如果想要使用其他 .proto 文件中定义的消息,可以将这些文件导入!

代码语言:javascript
代码运行次数:0
复制
import "myproject/other_protos.proto";

默认情况下你只能使用直接导入的 .proto 文件中的定义,然而,有时候你需要移动一个 .proto 文件到一个新的位置,可以不直接移动 .proto 文件,只需放入一个伪 .proto 文件在老的位置,然后使用import public转向新的位置。import public 依赖性会通过任意导入包含import public声明的proto文件传递。例如:

代码语言:javascript
代码运行次数:0
复制
// new.proto
// All definitions are moved here
代码语言:javascript
代码运行次数:0
复制
// old.proto
// This is the proto that all clients are importing.
// 这是所有客户端正在导入的proto
import public "new.proto";
import "other.proto";
代码语言:javascript
代码运行次数:0
复制
// client.proto
import "old.proto";
// You use definitions from old.proto and new.proto, but not other.proto
// 你可以使用来自new.proto的和old.proto的定义,而不是other.proto

通过在编译器命令行参数中使用-I/--proto_pathprotocal 编译器会在指定目录搜索要导入的文件。如果没有给出标志,编译器会搜索编译命令被调用的目录。通常你只要指定proto_path标志为你的工程根目录就好,并且指定好导入的正确名称就好。

3、使用proto2消息类型

在你的proto3消息中导入proto2的消息类型也是可以的,反之亦然,然后proto2枚举不可以直接在proto3的标识符中使用(如果仅仅在proto2消息中使用是可以的);

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 三、标准类型
  • 四、默认值
  • 五、枚举
    • 1、简单使用
    • 2、别名
    • 3、预留值
  • 六、使用其他消息类型
    • 1、简单例子
    • 2、导入定义*
    • 3、使用proto2消息类型
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档