vlambda博客
学习文章列表

你所不知道的protobuf3 高级用法

1 序言

Protobuf 是Google公司出品的,跨语言的,跨平台,可扩展序列化库。2016年, Proto3简化了proto2的开发 ,提高了性能,但也带了不兼容的问题。

2. proto3的改变
  • 移除了原始值字段的出现逻辑。

  • 移除了required字段

  • 移除了缺省值

  • 移除了unknown字段 (3.5中又加上了)

  • 移除了扩展,使用Any代替

  • 修复了未知的枚举值的语义

  • 添加了map类型

  • 添加了一些标准类似,比如time、动态数据的呈现

  • 可以使用JSON编码代替二进制proto编码

3. 语法

 3.1 入门案例

syntax = "proto3"//第一部分:指定版本号,默认proto2'

option go_package = "./animal"//第二部分

//定义message类型, 类似于定义结构体 第三部分
message GetAnimalRequest {
    string name = 1;
    int32 pageNum = 2;
    int32 pageSize = 3;
}

3.2. 基本数据类型

  • 数字类型:double、float、int32、int64、uint32、uint64、sint32、sint64: 存储长度可变的浮点数、整数、无符号整数和有符号整数

  • sint32/sint64: 采用ZigZag编码,所有的负数都使用正数表示,计算方式 ; 如非特殊需求,使用int32/int64即可;

  • 存储固定大小的数字类型:fixed32、fixed64、sfixed32、sfixed64: 存储空间固定

  • 布尔类型: bool

  • 字符串: string

  • bytes: 字节数组

3.3. 复杂类型:

  1. oneof:如果你有一组字段,同时最多允许这一组中的一个字段出现,就可以使用Oneof定义这一组字段

  2. map:类型需要设置键和值的类型 。

  3. reserved:忽略指定字段 ,可以通过字段编号范围或者字段名称指定保留的字段。

    message OtherType {
       reserved 5 to 6;
       reserved "f7", "f8";
       oneof keyIndex { //
           string name = 1;
           int32 id = 2;
       }
       map<string, string > properties = 4;
    //    string f5 = 5; 
    //    string f6 = 6;
    //    string f7 = 7;
    //    string f8 = 8;
       string f9 = 9;
    }
  4. 枚举类型 enum

    enum AppType {
       option allow_alias = true; //允许序号重复
       WeChat = 0;
       QQ = 1;
       Facebook = 3;
       Twitter = 3;
    }
    你所不知道的protobuf3 高级用法
    编译结果
  5. any类型:允许你处理嵌套数据,并不需要它的proto定义。一个Any以bytes呈现序列化的消息,并且包含一个URL作为这个类型的唯一标识和元数据。

    syntax = "proto3";
    import "google/protobuf/any.proto";

    option go_package="./proto";

    message Person {
       string id = 1;
       string name = 2;
       repeated google.protobuf.Any likes = 3;
    }

    编译结果:

    你所不知道的protobuf3 高级用法
    编译结果
4. protoc问题 补充

使用protoc,如果引入any包,需要把下载的include文件放入protoc目录下;如下图

图1
图2


大家好,我是SmileFisher

非常感谢您能读到到这里!如果有什么好的建议或者意见,希望可以不吝留言!