Protobuf语法学习

Protobuf

用protocolbuffer编译器来编译.proto文件(相当于protobuf语言的源文件)时,编译器将生成所选择语言的代码(作为protobuf语言的编译输出),这些代码可以操作在.proto文件中定义的消息类型,包括获取、设置字段值,将消息序列化到一个输出流中,以及从一个输入流中解析消息。

基本语法定义

  • 消息message
    使用message定义一个消息类型,大部分情况下编译成相应语言后作为一个”类型”。
  • 字段
    消息中的字段,包括整形(int32、int64、uint32、uint64),浮点(float/double),字符串(string),布尔值(bool)也可以自定义枚举(enum),其它消息类型也可以作为字段。一般编译后为对应语言的字段或属性
  • 标识号
    每个字段都有唯一的一个标识符(用来索引字段),也就是protobuf包体中是根据标识号作为key来取值的, 标识号和字段名的映射在proto文件编译后由收发两段持有,这样做的好处是可以减少包体大小,提高I/O速度。
  • 字段修饰符
    只有三种字段修饰符,每个字段必须有字段修饰符。
    • required:表示该字段的是必须设置的(该限制体现在:若在对应语言中该字段处于未被赋值/初始化的状态,则会报错)
    • optional: 表示该字段的是可选设置的,可通过[default = xxx]指定一个默认值,若没有显示指定默认值并且该字段没有被设置,则会使用该类型的默认值。
    • repeated: 表示该字段可以有多个值,一般会被编译为对应语言的集合类或数组。
示例:
message LoginRequest{
  required int32 id = 1;
  required string password = 2;
}
  • 注释(//)
    proto文件可以使用双斜杠(//)的语法格式进行注释。
  • 枚举(enum)
    使用关键字enum,作用是为字段指定某”预定义值序列”中的一个值,枚举常量必须在32位整形范围内,不推荐用负数,可以在消息内部、消息外部或者其它proto文件中定义枚举,这些枚举可以在任意proto文件中的任何消息定义中复用(前提需要导入定义)
  • 扩展(extend)

    message User{
    required int32 UserId = 1;
    extensions 5 to 10;
    }
    extend User{
    required string region = 6;
    }
  • 包(package)
    可以为proto文件添加可选的package声明符,相当于命名空间,用来防止不同消息类型的明明冲突,编译之后会映射到相应语言的命名空间/包上。

    package module.core;
    message Content{}
  • 服务(service)
    与消息、扩展、枚举都属于一等公民。如果想要将消息类型用在RPC(远程方法调用)系统中,可以在.proto文件中定义一个RPC服务接口,protocol buffer编译器将会根据所选择的不同语言生成服务接口代码及存根。如,想要定义一个RPC服务并具有一个方法,该方法能够接收 SearchRequest并返回一个SearchResponse,则可进行如下定义:
service SearchService{
    rpc Search (SearchRequest) returns (SearchResponse);
}

ProtoBuf编译器会产生一个抽象接口SearchService以及一个相应的存根实现,产生的存根提供了一个类型安全的接口用来完成基于protocolbuffer的RPC调用。所有service类都必须实现对应的Service接口,它提供了一种用来调用具体方法的方式,即在编译期不需要知道方法名及它的输入、输出类型。在服务器端,通过服务注册它可以被用来实现一个RPC Server。

  • 选项(options)
    在定义.proto文件时能够标注一系列的options。Options并不改变整个文件声明的含义,但却能够影响特定环境下处理方式。

其它设定说明

  • 导入定义
    如果要使用其它proto文件中定义的消息或枚举,则可以通过导入其它proto文件中的定义来使用它们,则需要使用import关键字添加一个导入声明。类似C/C++中的include 如:

    import "ecode.proto";
  • 嵌套消息
    可以在其它消息类型中定义、使用消息类型,即消息类型的嵌套,这种做法完全符合面向对象的设计思想。
  • 更新消息类型
    当一个已有的消息格式无法满足新需求,可以在消息中添加额外的字段更新消息类型,并且只要遵循一定的规则,可以不破坏已有代码使旧版本的代码仍然可用。
    • 不更改已有字段的标识号
    • 添加的字段必须是optional或repeated的(这样不会丢失任何required的元素,保证了良好的兼容性,新代码可以正确与老代码生成的消息交互,老代码只是简单将新字段忽略),逻辑上相当于新的消息类型 “继承” 于老的消息类型。
    • 可以移除非required字段,还要保证它们的标识号在新消息类型中不再使用(或重命名要移除的字段,如添加OBSOLETE_前缀),但这个操作需要更改旧代码,但这本身就是必要的,因为要删除的字段说明已经没用了故没有必要在代码中获取。
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值