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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM