• 阅读Google Protocol Buffers 指南,整理pb语法


    官方网站:

    https://developers.google.com/protocol-buffers/docs/proto3

    1、简单定义一个Message 类型

    pb语法文件以"*.proto"为文件扩展名。在版本proto3文件头需要包含版本类型“syntax = "proto3";”,缺省情况为proto2类型。

    官方示例:

    syntax = "proto3";

    message SearchRequest {
      string query = 1;
      int32 page_number = 2;
      int32 result_per_page = 3;
    }

    message为类标识符

    SearchRequest为类名

    string/int32为字段类型

    query/page_number/result_per_page为字段名称

    1/2/3为编号标签,用于序列化后内容标识,序号1~15需要1个字节,16~2047需要2个字节,最小编号为1,最大编号229-1或536870911。19000~19999系统预留,不可用。

    2、字段描述规则

    字段的规则主要分为单数和复数,用于描述字段是否是单个字段还是数组。默认情况下字段定义都是单数“singular”,如果需要定义数组需要在字段类型前面加“repeated”。

    3、添加注释

     可以在字段定义结束后加“//”注释,该注释会在生成的字段代码中。
    官方示例:

    message SearchRequest {

      string query = 1; 

      int32 page_number = 2;  // Which page number do we want?  

     int32 result_per_page = 3;  // Number of results to return per page.

    }

    4、保留字段

    编号定义后,无法更改,如果需要重新定义类型或删除旧的类型,需要在序列化文件中占位原定义的类型。这样才能保证更改后数据正常反序列化,并对以前数据兼容。否则数据格式不正确后,将导致对更改前的数据反序列化出错。

    官方示例:

    message Foo {
      reserved 2, 15, 9 to 11;
      reserved "foo", "bar";
    }

    5、字段类型

    .proto TypeNotesC++ TypeJava TypePython Type[2]Go TypeRuby TypeC# TypePHP Type
    double   double double float float64 Float double float
    float   float float float float32 Float float float
    int32 Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. int32 int int int32 Fixnum or Bignum (as required) int integer
    int64 Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. int64 long int/long[3] int64 Bignum long integer/string[5]
    uint32 Uses variable-length encoding. uint32 int[1] int/long[3] uint32 Fixnum or Bignum (as required) uint integer
    uint64 Uses variable-length encoding. uint64 long[1] int/long[3] uint64 Bignum ulong integer/string[5]
    sint32 Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. int32 int int int32 Fixnum or Bignum (as required) int integer
    sint64 Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. int64 long int/long[3] int64 Bignum long integer/string[5]
    fixed32 Always four bytes. More efficient than uint32 if values are often greater than 228. uint32 int[1] int uint32 Fixnum or Bignum (as required) uint integer
    fixed64 Always eight bytes. More efficient than uint64 if values are often greater than 256. uint64 long[1] int/long[3] uint64 Bignum ulong integer/string[5]
    sfixed32 Always four bytes. int32 int int int32 Fixnum or Bignum (as required) int integer
    sfixed64 Always eight bytes. int64 long int/long[3] int64 Bignum long integer/string[5]
    bool   bool boolean bool bool TrueClass/FalseClass bool boolean
    string A string must always contain UTF-8 encoded or 7-bit ASCII text. string String str/unicode[4] string String (UTF-8) string string
    bytes May contain any arbitrary sequence of bytes. string ByteString str []byte String (ASCII-8BIT) ByteString string
    • string, 默认值为空字符串.
    • bytes, 默认值为空字节数组.
    • bool, 默认值为false.
    • 数值类型, 默认值为0.
    • enums, 从0开始的枚举.
    • message对象列, 没有设置默认值,根据不同语言给定相应的规则
    • int32,uint32,int64,uint64、bool和枚举是兼容的,可以相互转换,更改字段类型后,可以向前和向后兼容,但会强制类型转化,会截断数值,如64变32位,以前的数据会只被读取32位值。
    • sint32和sint64彼此兼容,fixed32与sfixed32彼此兼容。

    6、枚举类型的定义

    官方示例:

    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;
    }

    enum为枚举关键字

    enum类型必须定义枚举值0.

    一般情况下不允许同值枚举存在。如果需要增加同值枚举需要添加“option allow_alias = true;”

    官方示例:

    enum EnumAllowingAlias {
      option allow_alias = true;
      UNKNOWN = 0;
      STARTED = 1;
      RUNNING = 1;
    }

    7、引用其他文件

    官方示例:

    import "myproject/other_protos.proto";

    在多次引用过程中也可以控制引用的作用域。加关键字“public”将可以被下下次引用使用。

    官方示例:

        // new.proto // All definitions are moved here

     
    // old.proto
    // This is the proto that all clients are importing.
    import public "new.proto";
    import "other.proto";
       old 引用了public new和other,other只能在old里面使用。
       
    // client.proto
    import "old.proto";
    // You use definitions from old.proto and new.proto, but not other.proto

    client引用了old,因为new在old引用中是public 的,所以client是可以使用new. 但不能使用other.

    7、嵌套类型

    message 可以嵌套多层message.
    message 可以嵌套 enum.
    官方示例:
    message Outer {                  // Level 0
      message MiddleAA {  // Level 1
        message Inner {   // Level 2
          int64 ival = 1;
          bool  booly = 2;
        }
      }
      message MiddleBB {  // Level 1
        message Inner {   // Level 2
          int32 ival = 1;
          bool  booly = 2;
        }
      }
    }

    8、Any类型

    PB支持未知类型。该类型包含任意序列化的消息作为字节,以及一个充当全局唯一标识符并解析为该消息类型的URL。要使用Any类型,您需要导入google / protobuf / any.proto。
    官方示例:
    import "google/protobuf/any.proto";

    message ErrorStatus {
      string message = 1;
      repeated google.protobuf.Any details = 2;
    }


    9、Oneof类型
    如果有一个包含多个字段的消息,并且最多可以同时设置一个字段,则可以通过使用该功能强制执行此行为并节省内存。
    Oneof字段就像常规字段,除了一个共享内存中的所有字段,最多可以同时设置一个字段。 设置任何成员自动清除所有其他成员。 可以根据选择的语言检查使用case()或WhereOneof()方法设置一个值中的值。
    官方示例:
    message SampleMessage {
      oneof test_oneof {
        string name = 4;
        SubMessage sub_message = 9;
      }
    }


    10、Map类型
    语法规则为:
    map<key_type, value_type> map_field = N;

    示例:
    map<string, Project> projects = 3;

    11、包Package
    我们可以在“.proto”文件中定义包,可以防止类的名称冲突,在我们使用过程可以加包名来定义字段类型。
    官方示例:
    package foo.bar;
    message Open { ... }

    使用时,
    message Foo {
      ...
      foo.bar.Open open = 1;
      ...
    }


  • 相关阅读:
    Jmeter之参数化
    安全测试-业务安全的些许“瞎说”
    (转)LR性能测试结果样例分析
    (转)使用 Nmon 监控 Linux 的系统性能
    Jmeter之断言
    自动化框架httpClient实例
    RabbitMQ集群 Docker一键部署
    使用swing构建一个界面(包含flow ,Border,Grid,card ,scroll布局)
    Jtable实现
    java 使用最新api操作mongodb
  • 原文地址:https://www.cnblogs.com/hobinly/p/7207778.html
Copyright © 2020-2023  润新知