Protobuf 属性解释

首先我们需要编写一个 proto 文件,定义我们程序中需要处理的结构化数据,在 protobuf 的术语中,结构化数据被称为 Message。proto 文件非常类似 java 或者 C 语言的数据定义,可以使用C或C++风格的注释。下面是一个proto文件的例子。

syntax = "proto3";
package tutorial;
 
 
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
 
 
message Person {
required string name = 1;
required int32 id = 2;        // Unique ID number for this person.
optional string email = 3;
 
 
 
enum PhoneType {
 
  MOBILE = 0;
  HOME = 1;
  WORK = 2;
 
}
 
 
message PhoneNumber {
 
  required string number = 1;
  optional PhoneType type = 2 [default = HOME];
 
}
 
repeated PhoneNumber phone = 4;
 
}
 
 
// Our address book file is just one of these.
 
message AddressBook {
repeated Person person = 1;
 
}

一个proto文件主要包含package定义、message定义和属性定义三个部分,还有一些可选项。

文件的第一行指定了你正在使用proto3语法:如果你没有指定这个,编译器会使用proto2。这个指定语法行必须是文件的非空非注释的第一个行。

1.1 定义package

Package在c++中对应namespace

对于Java,包声明符会变为java的一个包,除非在.proto文件中提供了一个明确有java_package。

1.2 定义message

Message在C++中对应class。Message中定义的全部属性在class中全部为private的。

Message的嵌套使用可以嵌套定义,也可以采用先定义再使用的方式。

Message的定义末尾可以采用java方式在不加“;”,也可以采用C++定义方式在末尾加上“;”,这两种方式都兼容,建议采用java定义方式。

向.proto文件添加注释,可以使用C/C++/java风格的双斜杠(//) 语法格式。

1.3 定义属性

属性定义分为四部分:标注+类型+属性名+属性顺序号+[默认值],其示意如下所示。

标注

类型

属性名

属性顺序号

[默认值]

required

string

name

= 1

[default=””];

其中属性名与C++和java语言类似,不再解释;下面分别对标注、类型和属性顺序号加以详细介绍。

其中包名和消息名以及其中变量名均采用java的命名规则——驼峰式命名法,驼峰式命名法规则见附件1。

1.3.1 标注

标注包括“required”、“optional”、“repeated”三种,其中

required表示该属性为必选属性,否则对应的message“未初始化”,debug模式下导致断言,release模式下解析失败;

optional表示该属性为可选属性,不指定,使用默认值(int或者char数据类型默认为0,string默认为空,bool默认为false,嵌套message默认为构造,枚举则为第一个)

repeated表示该属性为重复字段,可看作是动态数组,类似于C++中的vector。

如果为optional属性,发送端没有包含该属性,则接收端在解析式采用默认值。对于默认值,如果已设置默认值,则采用默认值,如果未设置,则类型特定的默认值为使用,例如string的默认值为””。

1.3.2 类型

Protobuf的属性基本包含了c++需要的所有基本属性类型。

protobuf属性

C++属性

java属性

备注

double

double

double

固定8个字节

float

float

float

固定4个字节

int32

int32

int32

使用变长编码,对于负数编码效率较低,如果经常使用负数,建议使用sint32

int64

int64

int64

使用变长编码,对于负数编码效率较低,如果经常使用负数,建议使用sint64

uint32

uint32

int

使用变长编码

uint64

uint64

long

使用变长编码

sint32

int32

int

采用zigzag压缩,对负数编码效率比int32高

sint64

int64

long

采用zigzag压缩,对负数编码效率比int64高

fixed32

uint32

int

总是4字节,如果数据>2^28,编码效率高于unit32

fixed64

uint64

long

总是8字节,如果数据>2^56,编码效率高于unit32

sfixed32

int32

int

总是4字节

sfixed64

int64

long

总是8字节

bool

bool

boolean

string

string

String

一个字符串必须是utf-8编码或者7-bit的ascii编码的文本

bytes

string

ByteString

可能包含任意顺序的字节数据

1.3.3 Union类型定义

Protobuf没有提供union类型,如果希望使用union类型,可以采用enum和optional属性定义的方式。

例如,如果已经定义了Foo、Bar、Baz等message,则可以采用如下定义。

message OneMessage {
 
  enum Type { FOO = 1; BAR = 2; BAZ = 3; }
 
  // 标识要填写的字段,必填
  required Type type = 1;
 
  // 将填写以下内容之一,可选
  optional Foo foo = 2;
  optional Bar bar = 3;
  optional Baz baz = 4;
 
}

1.3.4 message类型定义

Protobuf中定义一个数据结构需要用到关键字message,这一点和Java的class,Go语言中的struct类似。

message Address {
    required sint32 id = 1 [default = 1];
    required string name = 2 [default = '北京'];
    optional string pinyin = 3 [default = 'beijing'];
    required string address = 4;
    required bool flag = 5 [default = true];
}

1.3.4 enum类型定义

proto协议支持使用枚举类型,和正常的编程语言一样,枚举类型可以使用enum关键字定义在.proto文件中:

enum Age{
    male=1;
    female=2;
}

到此 Protobuf 属性解释介绍完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BasicLab基础架构实验室

你的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值