zoukankan      html  css  js  c++  java
  • proto3 笔记1

    定义 Message 类型, 例子如下:

    syntax = "proto3";
    
    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.
    }
    说明:

    1、proto3 格式的必须第一行指明版本号,  syntax = "proto3"; 

    2、所有的字段都是 Scalar Value Types

    3、象上面看到的,所有的字段定义都有一个唯一的数字标签,这些数字标签用来标识在消息二进制序列化时的顺序信息,序列化后,1~15占一个字节,16~2047占两个字节。(字段的类型和识别号码放在一起,下面可以看到 Scalar Value Types有15种,再加上标识号码, 所以只能 1-15 占一个字节, 16以上2个字节)
    所以你要注意,用1-15标识频繁出现的元素。 标识号码最小 1, 最大  is 229 - 1, 或者 536,870,911, 其中要排除 19000 到19999 这段保留段。

    Scalar Value Types

    在 proto 文件和各种语言中对应的类型关系如下图:

    image

    这些类型的默认值如下:

    • string  空字符串
    • bytes 空 bytes
    • bool 默认flase
    • 数字类型 默认 0
    • 枚举类型 默认第一个值, 而且第一个的数字编码必须是 0
    • message fields 默认 null
    • repeated  的字段默认是 null, 空的列表。

    带枚举的一个message 例子:

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

    对枚举来说, 如果设置了 option allow_alias = true;  就可以让枚举项的值一样,相当于起了别名。

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

    定义引用

    Message 可以使用其他 Message作为字段,即嵌套定义,比如下面定义:

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

    这里的  repeated  关键字相当于定义了一个对应的数组,数组元素是其后的类型, 数组的大小可以是0到很大, 由于历史原因,数值型的repeated字段后面最好加上[packed=true],这样能达到更好的编码效果。

    互相引用

    如果 proto 文件定义不在这个文件, 我们可以通过下面方式引入:

    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";
    // client.proto 文件
    import "old.proto";
    // You use definitions from old.proto and new.proto, but not other.proto

    public 的定义会一直嵌套带入 import。

    内部Message, 嵌套定义

    你可以在 message 内部定义 message,如下面代码:

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

    需要使用这个内部 message时,可以这么使用:

    message SomeOtherMessage {
      SearchResponse.Result result = 1;
    }

    由于有这个命名空间层级关系, 你可以这么定义:

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

    最里面的两个 message 的字段名称一样,只是字段类型不一样。

    参考资料:

    Language Guide (proto3)
    https://developers.google.com/protocol-buffers/docs/proto3?hl=zh-cn

  • 相关阅读:
    关于jetty服务器默认首页和端口设置
    yum提示Another app is currently holding the yum lock; waiting for it to exit...
    21.线程池ThreadPoolExecutor实现原理
    20.并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解
    19.并发容器之BlockingQueue
    18.一篇文章,从源码深入详解ThreadLocal内存泄漏问题
    17.并发容器之ThreadLocal
    16.并发容器之CopyOnWriteArrayList
    15.并发容器之ConcurrentLinkedQueue
    14.并发容器之ConcurrentHashMap(JDK 1.8版本)
  • 原文地址:https://www.cnblogs.com/ghj1976/p/4565846.html
Copyright © 2011-2022 走看看